Ruby on Rails表单中模型字段的默认值

时间:2011-01-19 14:32:12

标签: ruby-on-rails ruby database ruby-on-rails-3

我有一个Model,其中包含字段username, data, tags, date, votes。我有使用form_for的表单,它创建一个新项目并将其放入数据库。但是,您可以猜测我希望投票字段等于0,并且日期字段等于放入数据库时​​的当前日期。如何以及在何处将这些值设置/应用于项目?

我可以使用表单中的隐藏字段,但这会带来明显的问题(有人可能会将votes字段设置为大量数字)。

5 个答案:

答案 0 :(得分:10)

只需使用默认值;零,对于数据库中的投票,使用自动时间戳(created_at)而不是date,并且表单中的字段仅适用于您将设置的参数。不要忘记保护敏感属性。

class CreateModels < ActiveRecord::Migration
  def up
    create_table :models do |t|
      t.string :username
      t.text :data
      t.string :tags
      t.integer :votes, :default => 0

      t.timestamps # this will give you two automatic fields: created_at and updated_at
    end
  end
  …
end

class Model < ActiveRecord::Base
  attr_protected :votes #so that it cannot be set by mass assignment
  …
end

答案 1 :(得分:5)

我可以确认DB约束方法是最好的方法之一。 但并不总是可以使用。假设存在单个表继承,并且每个子模型需要不同的默认值。 比我建议把它放到模型中。让我举个例子:

class ChildModel < Model
  after_initialize :set_defaults
  private
  def set_defaults
    self.allowed_votes_per_person = 10 if self.new_record?
  end 
end

通过使用:after_initialize回调,无需创建和记住调用:new_default类似方法等。 它设置了所需的默认值,但是当一个人调用ChildModel.new

时,从界面的角度来看是不显眼的。

答案 2 :(得分:3)

一种简单的方法是在控制器上的create action上设置默认值。

@model = Model.new(params[:model])
@model.votes = 1
@model.date = Time.now
@model.save

另一种方式,也是更干净,就是在Model中创建一个方法。

class Model

def new_default(model)
  model = Model.new(model)
  model.votes = 1
  model.date = Time.now
end

所以在你的控制器中你会有:

@model = Model.new_default(params[:model])

if @model.save
   render something
else
   render something_else
end

答案 3 :(得分:1)

这是关于保护属性的截屏视频: http://railscasts.com/episodes/26-hackers-love-mass-assignment

Rails模型默认带有自动时间戳,created_at和updated_at字段是属性的名称。您不必担心设置它们,因为rails会为您处理。

答案 4 :(得分:0)

我没有特权评论其他人的答案,但对Nerian有一个相关的问题,所以我发布了这个。我正在使用像

这样的代码
before_create : create_rest
def create_rest
  15.times do
    self.players.build({:name => Rnlist.order("rand()").first.raname,
                        :cost => 140+rand(40),
                        :coop => rand(3)})
  end
end

在模型user.rb中。这段代码完美无缺,可以创建15个不同名称的玩家等等。但是如果我试图按照你建议的方式将属性放入玩家模型中(使用players_controller中的create方法),self.players.build方法会创建15名玩家拥有空属性而不会出现任何错误。我认为使用新方法而不是在players_controller中创建代码可以解决这个问题,但结果是一样的。 self.players.build方法可以导致问题吗?我检查了Ruby API for others.build()和Vinhboy.com blog,但无法解决此问题。