Reputation: 595
In my Rails 5.2 app, I have a polymorphic model Vehicle of types Car, Bike, Jeep etc. which has belongs_to association vehicle_type. I would like to validate associated record attribute display_name. The following code snippet does the job but I would like to know a better way to do this.
class Car < Vehicle
validates :vehicle_type,
:inclusion => {
:in => [VehicleType.find_by(display_name: 'four wheeler')],
:message => "A Car can only be of vehicle_type 'four wheeler'",
}
}
Upvotes: 0
Views: 928
Reputation: 296
I agree with Mathieu Larouche. One small thing I would add to this discussion is that this is not really a polymorphic association, as polymorphic associations are about how "a model can belong to more than one other model, on a single association". This is done via a combination of type
and id
fields (imageable_id
and imageable_type
, for example). See docs here.
It doesn't really affect the response your question, but I just wanted to mention it because polymorphic associations took me forever to wrap my head around, and I thought calling out the distinction could be helpful.
Upvotes: 0
Reputation: 627
I don't know what is the best way, but I'll share what i have done in one of my projects:
I decided to extend ActiveModel::Validator
and create my own validation for my polymorphic associations
In you case
class CarValidator < ActiveModel::Validator
def validate_vehicle_type(record)
# where did you save the veicle type associatuon?
unless VehicleType.find_by(display_name: record.veicle_type).exists?
record.errors.add :veicle_type, "This veicle type does not exist"
end
end
then validates with CarValidator
Upvotes: 0
Reputation: 131
You should put the validation on the id rather than the display name since you would have to refactor your code if you ever decide to change the display name.
class VehiculeType
FOUR_WHEELER = 1 (id of the four_wheeler type)
end
class Car < Vehicule
validate :validate_vehicule_type
private
def validate_vehicule_type
errors.add(:vehicule, "A Car can only be of vehicle_type 'four wheeler'") unless vehicule_type_id == VehiculeType::FOUR_WHEELER
end
end
Upvotes: 0