我有一个Model
,它有字段username, data, tags, date, votes
。我使用form_for
创建一个新项目并将其放入数据库中。然而,正如你可以猜到的,我希望投票字段等于0,并且日期字段等于当它放入数据库时的当前日期。如何以及在哪里设置/将这些值应用于项目?Ruby on Rails表格中模型字段的缺省值
我可以让它与表单中的隐藏字段一起工作,但是这带有明显的问题(有人可能会将votes
字段设置为大量数字)。
我有一个Model
,它有字段username, data, tags, date, votes
。我使用form_for
创建一个新项目并将其放入数据库中。然而,正如你可以猜到的,我希望投票字段等于0,并且日期字段等于当它放入数据库时的当前日期。如何以及在哪里设置/将这些值应用于项目?Ruby on Rails表格中模型字段的缺省值
我可以让它与表单中的隐藏字段一起工作,但是这带有明显的问题(有人可能会将votes
字段设置为大量数字)。
只需使用一个默认值;对于数据库中的投票为零,请使用自动时间戳(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
一个简单的方法是在控制器上的create action上设置默认值。
@model = Model.new(params[:model])
@model.votes = 1
@model.date = Time.now
@model.save
另一种方式,也是更干净的方法是在模型中创建一个方法。
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
这里有一个关于保护属性的截屏: http://railscasts.com/episodes/26-hackers-love-mass-assignment
Rails的模式在默认情况下,created_at配备了自动时间戳和的updated_at字段是属性的名称。你不必担心设置它们,这将导轨为你处理。
我可以证实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时保持不显眼。
我没有权限评论他人的答案,但有一个相关的问题Nerian,所以我张贴这个。我在模型user.rb中使用类似
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
。这段代码工作得非常好,并创建了15名具有不同名称的玩家等。但是,如果我试图按照您建议的方式(使用players_controller中的create方法)将属性放入玩家模型,self.players.build方法会创建15名具有空属性的玩家没有任何错误。我认为使用新方法而不是在players_controller中创建代码可以解决这个问题,但结果是一样的。 self.players.build方法是否会导致问题?我检查了Ruby API for others.build()和Vinhboy.com blog,但无法解决此问题。
+1用于将数据完整性业务逻辑放入数据库而不是模型中。 – Phrogz 2011-01-19 16:35:32