有没有办法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?( ‘登录’)
- 了解Ruby on Rails ActiveRecord模型访问器
- Ruby on Rails + PostgreSQL:自定义序列的使用
- 有没有办法使用HashWithIndifferentAccess序列化ActiveRecord的JSON属性?
- 多对多关系只能以Rails / Activerecord / devise的方式工作
- Rails:has_many有额外的细节吗?
- Ruby on Rails:从YAML文件加载种子数据
- 检索给定用户评论的所有post,Ruby on Rails
- Rails / ActiveRecord – AdapterNotSpecified,即使它是
- 获取所有类别和子类别的产品(rails,awesome_nested_set)