部分调用某些Activerecord对象属性的验证过程

时间:2016-02-01 00:17:02

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

我的情况是User has_one :addressAddress belongs_to :user。 在这些情况下,我需要能够验证地址对象:

用户注册后,他可以选择部分填写地址表单。在这种状态下,我想验证例如validates :phone_number, :postal_code, numericality: true,但是如果他愿意,用户可以将该字段留空。

当用户进行购买时,他必须填写地址表单。并且所有字段都必须通过validates presence: true +之前的验证进行验证。

我理解一种方法是将另一个参数附加到表单(即full_validation),然后添加一个自定义验证方法,该方法将检查此参数,然后完全验证所有属性。

我只是想知道是否有更高效,更简单的方法来实现这一目标。

到目前为止,我只找到了验证某些属性的方法(请参阅this blog post),但我还没有找到有关如何为某些属性调用部分验证过程的建议。

任何帮助/建议将不胜感激:)

2 个答案:

答案 0 :(得分:1)

对于您的第一个用例,您可以使用:allow_blank上的validates选项允许该字段为空白,即仅在该字段不为空时才验证该字段?

http://guides.rubyonrails.org/active_record_validations.html#allow-blank

对于这两种用例,您可以使用:if / :unless选项告诉Rails何时触发验证。这称为条件验证:

http://guides.rubyonrails.org/active_record_validations.html#conditional-validation

对于Address,您可以尝试这样的事情:

class Address
  belongs_to :user
  validates :phone_number, :postal_code, numericality: true, allow_blank: true, if: new_user?

  def new_user?
    user && user.new_record?
  end      
end

这为您的第一个用例提供了一个示例。至于第二种情况,您需要在User上使用条件验证,以确保在购买时存在地址。如何处理这取决于您的情况:您可以在User上设置一个标记,或者让该标记检查User的某些方面,例如存在任何给定用户的购买。

class User
  has_one :address
  has_many :purchases
  validates :address, presence: true, if: has_purchases?

  def has_purchases?
    purchases.exists?
  end
end

答案 1 :(得分:1)

#app/models/user.rb
class User < ActiveRecord::Base
    has_one :address, inverse_of: :user
end

#app/models/address.rb
class Address < ActiveRecord::Base
   belongs_to :user, inverse_of: :address

   validates :phone_number, :postal_code, numericality: true, if: ["phone_number.present?", "postal_code.present?"]
   validates :x, :y, :z, presence: true, unless: "user.new_record?"
end

-

用户注册后

使用if确定phone_numberpostal_code是否存在。

只有在提交的数据中存在数字才会验证它们的数值。 User是否是新的并不重要。

-

用户进行购买时

要进行购买,我认为必须创建User(否则他无法购买)。我使用user.new_record?方法来确定用户是否是新记录。

最终,我和我的@odaata的答案提到使用conditional evaluation (if / unless)来确定某些属性/凭据是否值得验证。

docs深入探讨了这个问题;我添加了inverse_of,因为它可以让您访问关联对象(允许您在user.x中调用Address)。

如果您提供有关如何管理purchase流程的更多背景信息,我将能够为其提供更好的条件逻辑。