2011-01-19 79 views
4

我有一个Model,它有字段username, data, tags, date, votes。我使用form_for创建一个新项目并将其放入数据库中。然而,正如你可以猜到的,我希望投票字段等于0,并且日期字段等于当它放入数据库时​​的当前日期。如何以及在哪里设置/将这些值应用于项目?Ruby on Rails表格中模型字段的缺省值

我可以让它与表单中的隐藏字段一起工作,但是这带有明显的问题(有人可能会将votes字段设置为大量数字)。

回答

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 
+0

+1用于将数据完整性业务逻辑放入数据库而不是模型中。 – Phrogz 2011-01-19 16:35:32

3

一个简单的方法是在控制器上的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 
4

我可以证实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时保持不显眼。

0

我没有权限评论他人的答案,但有一个相关的问题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,但无法解决此问题。