【发布时间】:2011-05-27 16:52:38
【问题描述】:
我正在研究 validates_presence_of 的实际工作原理。假设我有两个模型
class Project < ActiveRecord::Base
[...]
has_many :roles
end
和
class Role < ActiveRecord::Base
validates_presence_of :name, :project
belongs_to :project
end
我希望角色始终属于现有项目,但我刚刚从this example 发现这可能导致保存到数据库中的无效(孤立)角色。所以正确的做法是在我的角色模型中插入validates_presence_of :project_id,它似乎可以工作,即使我认为在语义上验证项目的存在而不是项目 ID 更有意义。
此外,我认为如果我只是验证 project_id 的存在,我可以放置一个无效的 id(对于一个不存在的项目),因为默认情况下 AR 不会向迁移添加完整性检查,即使我添加了它们手动一些数据库不支持它们(即带有 MyISAM 或 sqlite 的 MySQL)。这个例子证明了
# 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 gem,但除非绝对必要,否则我宁愿不将 gem 添加到我的项目中。
对此有什么想法吗?
更新
validates_presence_of :project 并在迁移中为 project_id 列添加:null => false 似乎是一种更清洁的解决方案。
【问题讨论】:
-
我强烈建议为此使用 validates_existence gem,因为它正是您所需要的。此外,它是一个相当小的依赖项。
-
只是一个快速的不 - 确保您也使用您的数据库进行验证。让生活更安全。
-
@Jits,我想我会这样做的。 @Chuck 我也会这样做,但这样我就不会出现验证错误,所以我仍然需要在 ruby 级别进行验证。
标签: ruby-on-rails validation activerecord