我有一個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