我正在调查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