Ruby on rails Ruby类评估,验证包含动态数据的

Ruby on rails Ruby类评估,验证包含动态数据的,ruby-on-rails,ruby,class,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 class Fooself.allowed类型的包含 def self.allowed_类型 #

如果我有一个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
class Fooself.allowed类型的包含
def self.allowed_类型
#一些返回可枚举项的代码
结束
结束
这不起作用,因为在评估验证时尚未定义允许的类型方法。我能想到的所有修复基本上都围绕着将方法定义移到验证之上,以便在需要时可用

我明白这可能是一个编码风格的问题(我希望所有的验证都在模型的顶部,方法在底部),但我觉得应该有某种解决方案,可能包括对初始模型负载的惰性评估


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

为此,您应该能够使用
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
class Foolambda{| foo | foo.allowed_types}
允许的def_类型
#一些返回可枚举项的代码
结束
结束
这样,它将在每次验证时评估lambda块,并将Foo实例传递给该块。然后,它将从该实例中允许的_类型返回值,以便动态验证


还要注意,我从允许的方法声明中删除了
self.
,因为这将创建一个类方法,而不是您在这里想要的实例方法。

方法的validates\u inclusion\u选项似乎不接受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

非常感谢,这正是我想要做的,只是没有意识到将对象传递到lambda会传递正在验证的对象。您可以使用
:in=>lambda(&:allowed_types)
获得更简洁的语法。使用新的lambda语法:
验证:value的包含,in:->(o){o.allowed_types}
@eightbitraptor…尝试
:in=>Foo.allowed_types
而不是
:in=>self.allowed_types
…因为我认为
self
将引用
Foo
的对象