如果我有一个ActiveRecord模型如下
class Foo < ActiveRecord::Base
validates_inclusion_of :value, :in => self.allowed_types
def self.allowed_types
# some code that returns an enumerable
end
end
这不起作用,因为在评估验证时尚未定义allowed_types方法。我能想到的所有修复基本上都围绕着将方法定义移到验证之上,以便在需要时可用。
我理解这可能更像是一个编码风格的问题而不是任何东西(我希望我的所有验证都在模型的顶部和底部的方法)但我觉得应该有一些解决方案,可能涉及惰性评估初始模型负载?
是我想要做的甚至可能吗?我应该只是定义验证上方的方法,还是有更好的验证解决方案来实现我想要的。
答案 0 :(得分:10)
您应该能够使用lambda
语法来实现此目的。也许是这样的:
class Foo < ActiveRecord::Base
validates_inclusion_of :value, :in => lambda { |foo| foo.allowed_types }
def allowed_types
# some code that returns an enumerable
end
end
这样它将在每次验证时评估lambda块并将Foo的实例传递给块。然后它将从该实例中的allowed_types返回值,以便可以动态验证它。
另请注意,我从allowed_types方法声明中删除了self.
,因为这会创建一个类方法,而不是您想要的实例方法。
答案 1 :(得分:0)
validates_inclusion_of方法的:in选项似乎不接受lambda或Proc。这是另一种方法:
validates_each :product_id do |record, attrib, value|
begin
Product.find(value)
rescue ActiveRecord::ActiveRecordError
record.errors.add attrib, 'must be selected from list.'
end
end