Rails 5: Adding conditional custom validations
10,482
Solution 1
When you fix the missing closing end
to opened if
in expiration_date_cannot_be_in_the_past
, you can have the following working:
validate :expiration_date_cannot_be_in_the_past, if: :paid_with_card?
Solution 2
You can use each validator. For this you have to follow these steps:
- Create a folder named
validators
inside yourapp
directory. - Create a file named
some_validator.rb
Write codes as like:
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
end
Now validates by this custom validator, as like:
validates :attribute_name, some: true
Make sure your are giving the same name on validator. You can write the multiple conditions inside this custom validator.
Solution 3
You missed end, corrected code:
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
Solution 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
Author by
David B.
Updated on June 04, 2022Comments
-
David B. almost 2 years
I would like to add a conditional custom validation to a model
Rails allows to create methods in order to create custom validations
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
It also allows to create conditional validations
class Order < ApplicationRecord validates :card_number, presence: true, if: :paid_with_card? def paid_with_card? payment_type == "card" end end
How can I mix both ?
My guess would be something like
validate :condition, if: :other_condition
But this creates a SyntaxError:
syntax error, unexpected end-of-input, expecting keyword_end
-
craigcaulfield over 5 yearsCode is always good, but it also helps to add some comments or context about how this solves the original question.
-
Greenstick over 5 yearsEchoing @craigcaulfield; please add some comments around how this solves the original question.