例如,如果我有一个用户模型并且我只需要验证登录(这可以通过ajax验证表单时发生),那么如果我使用User模型中定义的相同模型验证而不实际实例化User实例将会很棒.
所以在控制器中我可以编写类似的代码
User.valid_attribute?(:login, "login value")
无论如何我能做到吗?
由于验证在实例上运行(并且它们使用实例的errors属性作为错误消息的容器),因此如果没有实例化对象,则无法使用它们.话虽如此,您可以将此需要的行为隐藏到类方法中:
class User < ActiveRecord::Base def self.valid_attribute?(attr, value) mock = self.new(attr => value) unless mock.valid? return mock.errors.has_key?(attr) end true end end
现在,你可以打电话
User.valid_attribute?(:login, "login value")
就像你想要的那样.
(理想情况下,您将该类方法直接包含在ActiveRecord :: Base中,以便每个模型都可以使用它.)
感谢米兰的建议.受它的启发,我创建了一个简单的模块,可用于将此功能添加到任何类.请注意,原来的Milans建议有一个逻辑错误:
return mock.errors.has_key?(attr)
显然应该是:
return (not mock.errors.has_key?(attr))
我已经测试了我的解决方案,它应该可以工作,但是我不能保证.这是我光荣的解决方案.如果你拿走模块的东西,基本上是一个2线程..它接受方法名称作为蜇或符号.
module SingleAttributeValidation def self.included(klass) klass.extend(ClassMethods) end module ClassMethods def valid_attribute?(attr, value) mock = self.new(attr => value) (not mock.valid?) && (not mock.errors.has_key?(attr.class == Symbol ? attr : attr.to_sym)) end end end