有没有办法validationActiveRecord上的特定属性而不首先实例化对象?

例如,如果我有一个用户模型并且我只需要validation登录(这可以通过ajaxvalidation表单时发生),如果我使用User模型中定义的相同模型validation而不实际实例化User实例,那将会很棒。

所以在控制器中,我可以编写类似的代码

User.valid_attribute?(:login, "login value") 

无论如何我能做到吗?

由于validation在实例上运行(并且它们使用实例的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中,以便每个模型都可以使用它。)

感谢米兰的建议。 受它的启发,我创建了一个简单的模块,可用于将此function添加到任何类。 请注意,原来的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 

要使用标准validation例程:

 User.new(:login => 'login_value').valid? 

如果这对您不起作用,请为此构建自定义类方法:

 class User < ActiveRecord::Base validate do |user| user.errors.add('existing') unless User.valid_login?(user.login) end def self.valid_login?(login) # your validation here !User.exist?(:login=> login) end end 

我有一段时间在Rails 3.1中使用它。 这终于奏效了。 (不确定这是否是最好的方式,我有点新手。) 我遇到的问题是该值被设置为键入ActiveSupport :: SafeBuffer,并且validation失败。

 def self.valid_attribute?(attr, value) mock = User.new(attr => "#{value}") # Rails3 SafeBuffer messes up validation unless mock.valid? return (not mock.errors.messages.has_key?(attr)) end return true end 

我已经使用了自定义类解决方案,但我只是想确保没有更好的方法

 class ModelValidator def self.validate_atrribute(klass, attribute, value) obj = Klass.new obj.send("#{attribute}=", value) obj.valid? errors = obj.errors.on(attribute).to_a return (errors.length > 0), errors end end 

我可以像使用它一样

有效,错误= ModelValidator.validate_attribute(用户,“登录”,“humanzz”)

 class User < ActiveRecord::Base validates_each :login do |record, attr, value| record.errors.add attr, 'error message here' unless User.valid_login?(value) end def self.valid_login?(login) # do validation end end 

只需调用User.valid_login?(登录)即可查看登录本身是否有效

您建议的’valid_attribute’方法的实现:

 class ActiveRecord:Base def self.valid_attribute?(attribute, value) instance = new instance[attribute] = value instance.valid? list_of_errors = instance.errors.instance_variable_get('@errors')[attribute] list_of_errors && list_of_errors.size == 0 end end 

怎么样:

User.columns_hash.has_key?( ‘登录’)