validates_presence_of 是需要 has_many 关系的首选技术吗
基本上:我的模型需要至少存在一个关联模型的实例。我应该使用 validates_presence_of 来断言此验证,还是应该编写一些自定义验证代码?
以下是我的模型的要点:(
class Event < ActiveRecord::Base
has_and_belongs_to_many :channels
validates_presence_of :channels, :message => "can't be empty"
end
我假设如果我使用 has_many
代替 has_and_belongs_to_many
,情况会是一样的。)
而不是 validates_presence_of
>行我可以这样做:
def validate
errors.add(:channels, "can't be empty") if channels.size < 1
end
我在我正在开发的Rails应用程序中将后者替换为前者,并且想知道是否可能存在任何问题。
因此,为了更加确定,我编写了以下 rspec 覆盖范围,并且两种实现的响应相同:
describe Event do
before do
@net = Factory.create(:network)
@net_config = Factory.create(:network_config, :network => @net)
end
it "must have a channel" do
e = Factory.build(:event, :network => @net, :channels => [])
e.should have(1).error_on(:channels)
end
end
也就是说,如果我删除验证代码,则上述规范将失败;如果我输入任一版本的验证代码,上述规范都会通过。
所以我可能会认为我的新实现没问题。但我读到 validates_presence
会触发数据库加载,这反过来会清除由嵌套属性构造的任何内存中对象。另一方面,proxy_target 方法将返回内存中的对象而不触发加载。 proxy_target 上的一些链接:http://rubydoc.info/docs /rails/ActiveRecord/Associations/AssociationProxy http://withoutscope.com/2008/8/22/don-t-use-proxy_target-in-ar-association-extensions
在我的特殊情况下,我没有使用 ActiveRecord: :Relation,但我想知道我是否需要对此保持谨慎。
Basically: My model requires at least one instance of an associated model be present. Should I use validates_presence_of
to assert this validation, or should I write some custom validation code?
Here are the essentials of my model:
class Event < ActiveRecord::Base
has_and_belongs_to_many :channels
validates_presence_of :channels, :message => "can't be empty"
end
(I assume things would be the same if I used has_many
in place of has_and_belongs_to_many
.)
Instead of the validates_presence_of
line I could do this:
def validate
errors.add(:channels, "can't be empty") if channels.size < 1
end
I replaced the latter with the former in the Rails app I'm working on and am wondering if there might be any problems.
So to be more sure, I wrote the following rspec coverage, and both implementations respond the same:
describe Event do
before do
@net = Factory.create(:network)
@net_config = Factory.create(:network_config, :network => @net)
end
it "must have a channel" do
e = Factory.build(:event, :network => @net, :channels => [])
e.should have(1).error_on(:channels)
end
end
That is, if I remove the validation code, the above spec fails; if I put in either version of the validation code, the above spec passes.
So I might assume that my new implementation is ok. But I've read that validates_presence
triggers a database load which, in turn, would wipe out any in-memory objects constructed from nested attributes. The proxy_target method
, on the other hand, will return the in-memory objects without triggering a load. Some links on proxy_target
: http://rubydoc.info/docs/rails/ActiveRecord/Associations/AssociationProxy http://withoutscope.com/2008/8/22/don-t-use-proxy_target-in-ar-association-extensions
In my particular case I'm not using ActiveRecord::Relation
, but I wonder if I need to be cautious about this.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论