【问题标题】:Validating only one attribute using ActiveRecord::Base#valid?使用 ActiveRecord::Base#valid 仅验证一个属性?
【发布时间】:2014-11-20 17:36:11
【问题描述】:

我正在寻找一种仅在一个属性上使用ActiveRecord::Base#valid? 的方法。考虑以下示例,灵感来自RailsGuides

class Product < ActiveRecord::Base
  belongs_to :company

  validates :legacy_code, format: { with: /\A[a-zA-Z]+\z/ }
  validates :name, uniqueness: { scope: :company }
end

由于name 验证,调用Product#valid? 将触发SQL 查询:

Product.new(legacy_code: "helloworld", company: c).valid?
  Product Exists (0.3ms)  SELECT  1 AS one FROM "products"  WHERE ("products"."name" IS NULL AND "products"."company_id" = 1) LIMIT 1
=> true

现在,我只想验证 legacy_code 属性:

Product.new(legacy_code: "helloworld").valid?
  Product Exists (0.2ms)  SELECT  1 AS one FROM "products"  WHERE ("products"."name" IS NULL AND "products"."company_id" IS NULL) LIMIT 1
=> true

看到问题了吗?我喜欢使用 Product#valid?(:legacy_code) 之类的东西,并避免尝试验证我不关心的属性的查询。

到目前为止,我的解决方案是使用我可以独立调用的Product#valid_legacy_code? 方法,并在我的模型的验证声明中调用此方法。

【问题讨论】:

    标签: ruby-on-rails ruby validation rails-activerecord


    【解决方案1】:

    我最终为此写了一个 gem:https://github.com/KevinBongart/valid_attribute

    # Test only one attribute:
    product.valid_attribute?(:company)      # => true
    product.valid_attribute?(:name)         # => true
    product.valid_attribute?(:legacy_code)  # => false
    
    # Test several attributes at once, like a boss:
    product.valid_attribute?(:company, :name)               # => true
    product.valid_attribute?(:company, :name, :legacy_code) # => false
    
    # Wow, you can even filter down to a specific validator:
    product.valid_attribute?(name: :format)                     # => true
    product.valid_attribute?(name: [:format, :uniqueness])      # => true
    product.valid_attribute?(name: :format, company: :presence) # => true
    

    【讨论】:

      猜你喜欢
      • 2018-01-03
      • 2011-06-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-06-21
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多