Ruby on rails Ruby类评估,验证包含动态数据的
如果我有一个ActiveRecord模型,如下所示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_类型 #
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
的对象