【问题标题】:Rails 5: Adding conditional custom validationsRails 5:添加条件自定义验证
【发布时间】:2017-08-07 14:01:33
【问题描述】:

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

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

【问题讨论】:

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


    【解决方案1】:

    当您将缺少的关闭end 修复为在expiration_date_cannot_be_in_the_past 中打开的if 时,您可以进行以下工作:

    validate :expiration_date_cannot_be_in_the_past, if: :paid_with_card?
    

    【讨论】:

      【解决方案2】:

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

      • 在您的app 目录中创建一个名为validators 的文件夹。
      • 创建一个名为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

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

      【讨论】:

        【解决方案3】:

        你错过了结尾,更正了代码:

        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
        

        【讨论】:

          【解决方案4】:
          class User < ApplicationRecord
            validate :email_not_changeable, on: :update
          
            private
          
            def email_not_changeable
              return unless email_changed? && persisted?
          
              errors.add(:email, "can't be changed")
            end
          end
          

          【讨论】:

          • 代码总是好的,但它也有助于添加一些关于如何解决原始问题的 cmets 或上下文。
          • 呼应@craigcaulfield;请围绕如何解决原始问题添加一些 cmets。
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-05-10
          • 1970-01-01
          相关资源
          最近更新 更多