【问题标题】:Rails 3: validates :presence => true vs validates_presence_ofRails 3:验证 :presence => true vs validates_presence_of
【发布时间】:2011-03-25 19:04:09
【问题描述】:

validates :presencevalidates_presence_of 有什么区别?查看ActiveModel 看起来他们以相同的方式设置验证。但是,给定以下模型定义:

class Account < ActiveRecord::Base
  has_one :owner_permission, :class_name => 'AccountPermission', :conditions => { :owner => true, :admin => true }
  has_one :owner, :class_name => 'User', :through => :owner_permission, :source => :user

  validate :owner, :presence => true
  validates_associated :owner
end

Account 的实例上调用 save 不会验证所有者的存在。不过,如果我使用validates_presence_of,它会的。

【问题讨论】:

    标签: ruby-on-rails-3


    【解决方案1】:

    所有validates_whatever_of :attr 宏所做的就是调用validates :attr, :whatever =&gt; true

    问题是您使用的是validate 而不是validates

    【讨论】:

    • 谢谢。我现在真的很笨。
    • 但是为什么在像Agile Web Development with Rails 这样的书中没有提到validates_whatever_of 的验证方式,所有的验证示例都是使用validates :attr, :whatever =&gt; true 完成的?
    • @Ans validates 被认为是 Rails 3.x 的当前语法,validates_something_of 属于 Rails 2.x 时代
    • @mlibby 您能否详细说明这一点,或者提供一些确认这一点的文档参考?这意味着validates_presence_of 机制更有效。如果是这种情况,那么我想知道为什么 Rails 3/4 方法是使用 validates presence :true
    • 当然github.com/rails/rails/blob/master/activemodel/lib/active_model/… 显示validates_presence_of 的代码,github.com/rails/rails/blob/master/activemodel/lib/active_model/… 显示validates。在后一种情况下,第 113 - 119 行是直接调用验证器可以避免的额外工作。在效率方面,它只影响应用程序加载时间(当 ActiveRecord 文件被评估时),而不是运行时间本身。
    【解决方案2】:

    在 Rails 3.x 和 4.x 中 - 现在鼓励使用以下语法:

    validates :email, presence: true
    validates :password, presence: true
    

    而不是2.x的方式:

    validates_presence_of :email
    validates_presence_of :password
    

    【讨论】:

    • 值得注意的是(正如@mlibby 上面所做的那样)Rails2 validates_* 更高效,因为它们立即使用适当的验证器调用validates_with,而不是解析参数并尝试不同的验证器。比较 the Rails2 waythe Rails3+ way
    【解决方案3】:

    其实 validates 和 validates_presence_of 并不完全相等!

    validates_presence_of 还允许您通过示例懒惰地检查字段中的值是否包含在另一个表中。

    这样:

    validates_presence_of :pay_type, :inclusion => PaymentType.names
    

    这是你不能用这样的东西轻易做到的事情

    validates :pay_type, presence, :inclusion => PaymentType.names
    

    因为包含仅在第一次评估(不是以惰性方式)

    【讨论】:

      【解决方案4】:

      当您想要包含 :foo 的其他验证(例如长度或唯一性)时,我会认为使用 validates :foo presence: true 是合适的。但是,如果您知道属性需要的唯一验证是存在,那么validates_presence_of 似乎更有效。

      所以:

      validates :foo, length: {maximum: 50}, uniqueness: true, 
                      format: {with: /bar/}, 
                      presence: true # lots of validations needed
      

      但是:

      validates_presence_of :foo # only presence validation needed
      

      【讨论】:

        猜你喜欢
        • 2011-05-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-01-23
        • 2023-04-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多