我正在調查validates_presence_of實際如何工作。假設我有兩個型號validates_presence_of與belongs_to關聯,正確的方式
class Project < ActiveRecord::Base
[...]
has_many :roles
end
和
class Role < ActiveRecord::Base
validates_presence_of :name, :project
belongs_to :project
end
我希望它讓角色始終屬於現有的項目,但我剛剛從this example發現,這可能會導致保存無效(孤立的)角色進入數據庫。所以正確的做法是在我的Role模型中插入validates_presence_of :project_id
,它似乎工作,即使我認爲語義上有更多的意義來驗證項目的存在而不是項目ID。
除此之外,我想我可以把一個無效的id(對於一個不存在的項目),如果我只是驗證project_id的存在,因爲默認情況下AR不會爲遷移添加完整性檢查,即使我添加他們手動某些數據庫不支持他們(即MySQL與MyISAM或sqlite)。這個例子證明
# with validates_presence_of :name, :project, :project_id in the role class
Role.create!(:name => 'foo', :project_id => 1334, :project => Project.new)
AREL (0.4ms) INSERT INTO "roles" ("name", "project_id") VALUES ('foo', NULL)
+----+------+------------+
| id | name | project_id |
+----+------+------------+
| 7 | foo | |
+----+------+------------+
當然我不會寫這樣的代碼,但我想阻止這種在DB錯誤的數據。
我想知道如何確保一個角色總是有一個(真實的和保存的)項目關聯。
我發現了validates_existence寶石,但我寧願不添加寶石到我的項目中,除非是絕對必要的。
對此有何想法?
更新
validates_presence_of :project
和在遷移PROJECT_ID列添加:null => false
似乎是一個清潔的解決方案。
我強烈建議使用validates_existence gem來做這件事,因爲它正是你需要的。此外,它具有相當小的依賴性。 – Jits 2011-06-02 13:47:50
只是一個快速不 - 確保你使用你的數據庫來驗證。讓生活更安全。 – CharlesJHardy 2011-06-02 17:34:20
@Jits,我想我會那樣做的。 @Chuck我也會這樣做,但這樣我就不會有驗證錯誤,所以我仍然需要在ruby級別進行驗證。 – Fabio 2011-06-06 16:57:21