Rails 5:添加条件自定义验证

时间:2017-03-16 11:53:11

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

我想为模型添加条件自定义验证

Rails允许创建方法以创建自定义验证

class Invoice < ApplicationRecord
  validate :expiration_date_cannot_be_in_the_past

  def expiration_date_cannot_be_in_the_past
    if expiration_date.present? && expiration_date < Date.today
      errors.add(:expiration_date, "can't be in the past")
  end
end

它还允许创建条件验证

class Order < ApplicationRecord
  validates :card_number, presence: true, if: :paid_with_card?

  def paid_with_card?
    payment_type == "card"
  end
end

我如何混合使用?

我的猜测就像是

validate :condition, if: :other_condition

但这会创建一个SyntaxError:

syntax error, unexpected end-of-input, expecting keyword_end

4 个答案:

答案 0 :(得分:4)

当您在end中将缺失的结束if修复为已打开的expiration_date_cannot_be_in_the_past时,您可以执行以下操作:

validate :expiration_date_cannot_be_in_the_past, if: :paid_with_card?

答案 1 :(得分:3)

您可以使用每个验证器。为此,您必须按照以下步骤操作:

  • validators目录中创建名为app的文件夹。
  • 创建名为some_validator.rb
  • 的文件
  • 编写代码如下:

    class SomeValidator < ActiveModel::EachValidator
     def validate_each(object, attribute, value)
       return unless value.present?
       if some_condition1
         object.errors[attribute] << 'error msg for condition1'
       end
      object.errors[attribute] << 'error msg 2' if condition2
      object.errors[attribute] << 'error msg 3' if condition3
      object.errors[attribute] << 'error msg 4' if condition4
    end
    

  • 现在由此自定义验证程序验证,如: validates :attribute_name, some: true

  • 确保您在验证器上使用相同的名称。您可以在此自定义验证程序中编写多个条件。

答案 2 :(得分:2)

你错过了结束,纠正了代码:

class Invoice < ApplicationRecord
  validate :expiration_date_cannot_be_in_the_past

  def expiration_date_cannot_be_in_the_past
    if expiration_date.present? && expiration_date < Date.today
      errors.add(:expiration_date, "can't be in the past")
    end # this end you missed in code
  end
end

答案 3 :(得分:1)

class User < ApplicationRecord

  validate :email_not_changeable, on: :update

  private

  def email_not_changeable
    if self.email_changed? && self.persisted?
      errors.add(:email, "can't be changed")
    end
  end
end