2011-01-19 77 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,但無法解決此問題。