Ruby类评估,validates_inclusion_of与动态数据

时间:2011-08-18 10:19:45

标签: ruby-on-rails ruby class

如果我有一个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方法。我能想到的所有修复基本上都围绕着将方法定义移到验证之上,以便在需要时可用。

我理解这可能更像是一个编码风格的问题而不是任何东西(我希望我的所有验证都在模型的顶部和底部的方法)但我觉得应该有一些解决方案,可能涉及惰性评估初始模型负载?

是我想要做的甚至可能吗?我应该只是定义验证上方的方法,还是有更好的验证解决方案来实现我想要的。

2 个答案:

答案 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