我正在寻找一些关于ActiveRecord在执行从ActiveRecord :: Base继承的类的实例的验证时实际正在做什么的澄清。
为了讨论的目的,这里有一个例子(你可以假设bar是AR迁移生成的foos表中的一列)
class Foo < ActiveRecord::Base
def bar
read_attribute(:bar).length
end
end
f = Foo.new
f.bar = 'abcdefg'
f.bar => 7
f.read_attribute(:bar) => 'abcdefg'
我想了解的是ActiveRecord何时调用.valid? (或任何调用验证的方法)是否经过f.bar验证,或者f.read_attribute(:bar)已经过验证?
答案中是否有一些特殊情况?例如,在使用唯一性验证器或自定义验证器时。
同样重要:当AR写入生成插入或更新语句以将对象写入数据库时,属性值是持久的,还是从具有表的列名称的函数返回的值?
答案 0 :(得分:2)
有趣的问题,所以我进行了实验。
存在的验证位于访问者方法f.bar
上,不在f.read_attribute(:bar)
但是,唯一性验证将测试条形码值为7
的记录不在数据库中,因此唯一性验证将无法按预期工作。
对于唯一性,您可能希望在测试f.read_attribute(:bar)
尚未存在的情况下进行自定义验证(如果存在,则它不是同一记录)
自定义验证器当然是自定义的,因此您可以明确使用f.bar
或f.read_attribute(:bar)
,具体取决于哪种方式最符合您的需求。