我想为模型添加条件自定义验证
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
答案 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