当前位置:  开发笔记 > 后端 > 正文

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

如何解决《有没有办法验证ActiveRecord上的特定属性而不首先实例化对象?》经验,为你挑选了2个好方法。

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

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

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

无论如何我能做到吗?



1> Milan Novota..:

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


请注意,根据Timo的回答,行返回mock.errors.has_key?(attr)`肯定应该是`return(而不是mock.errors.has_key?(attr))`.除此之外,答案是有效的.

2> Timo..:

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

推荐阅读
路人甲
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有