Reputation: 5073
Let's say I have a before_validation that checks to make sure the first letter of a name is "y":
before_validation :check_name_first_letter_is_y
But I want to make sure that the first name is also present:
validates :name, presence: true
But this will run the before_validation BEFORE validating if there's a first name present, right? How would I check if a name is present before running my before_validate?
I could try:
after_validation :check_name_first_letter_is_y
But will that stop the save method if I return false? Or is it too late because it's already been validated?
Upvotes: 0
Views: 447
Reputation: 44685
You can simply add a second format validation:
validates :name, presence: true, format: { with: /^y/, allow_blank: true }
Upvotes: 1
Reputation: 38645
It might be easier to do this in one call as follows (if I didn't misread your question!):
validates :name, presence: ->(rec) { rec.name.initial == 'Y' }
Update:
Introduce a new ActiveModel::EachValidator
that checks the first character in the name to be y
and use the presence validator as you normally would, but ensure presence validator comes before the name
validator so that presence check is done before checking first letter.
# app/validators/NameValidator.rb
class NameValidator < ActiveModel::EachValidator
def validate_each(record, attribute, value)
if value.initial != 'y'
record.errors[attribute] << (options[:message] || "First letter in name must be `y`")
end
end
end
Then in your model, use the following two validations:
validates :name, presence: true
valdiates :name, name: true
Please refer: http://api.rubyonrails.org/classes/ActiveModel/Validator.html.
Also would suggest you to come up with a "Railsy" name for NameValidator
class!
Upvotes: 1