I have an app where I have a list of Car
s. I have a form above that can filter them based on different attributes. I wish to add filtering based on their model and sub-models.
Each car already has a Manufacturer
and these have models and then sub-models.
How can I structure this in Rails? Do I have a Modell
and a SubModell
(using those names to stop conflicting with rails own naming). or is there a better way?
I wish to be able to return the Manufacturer and Model and Sub Model directly from a car though. Like so:
c = Car.first
c.manufacturer # => "Ford"
c.model # => "Mondeo"
c.sub_model # => "Estate"
Is this possible?
Neil, Thanks in advance
CodePudding user response:
Yes, you can do this, the convention would be...
class VehicleManufacturer
has_many vehicle_models
end
class VehicleModel
has_many vehicle_sub_models
belongs_to :vehicle_manufacturer
end
class VehicleSubModel
belongs_to :vehicle_model
has_many :vehicles
delegate :vehicle_manufacturer, to: :vehicle_model
end
class Car
belongs_to vehicle_sub_model
delegate :vehicle_model, :vehicle_manufacturer, to: :vehicle_sub_model
delegate :name, to: :vehicle_manufacturer, prefix: true
delegate :name, to: :vehicle_model, prefix: true
delegate :name, to: :vehicle_sub_model, prefix: true
end
This will let you do...
c = Car.first
c.vehicle_manufacturer_name # => "Ford"
c.vehicle_model_name # => "Mondeo"
c.vehicle_sub_model_name # => "Estate"
You would only need to assign the correct vehicle_sub_model
to the car
and the other classes would automatically be available.
In your case, you already have a vehicle_manufacturer
association in the car
model, so you don't need the delegation to vehicle_manufacturer
in the model, but you would still need to assign the vehicle_sub_model
to the car (otherwise you won't know what model / sub_model the car is)
CodePudding user response:
Here is my solution, very close to what Steve has proposed:
With this solution, a car might have several manufacturers without having a sub model linked (optional: true
)
class VehicleManufacturer
has_many :vehicle_models
has_many :car_vehicle_manufacturers
has_many :cars, through: :car_vehicle_manufacturers
end
class VehicleModel
has_many :vehicle_sub_models
end
class VehicleSubModel
belongs_to :vehicle_model
end
class Car
# Limitation here, in case there is a "sub-sub-model" or if there is no "sub-model" but directly a model.
belongs_to :vehicle_sub_model, optional: true
has_many :car_vehicle_manufacturers
has_many :vehicle_manufacturers, through: :car_vehicle_manufacturers
# Pay attention to the eager loading with delegation, it won't work.
delegate :vehicle_model, :vehicle_manufacturer, to: :vehicle_sub_model
delegate :name, to: :vehicle_model, prefix: true
delegate :name, to: :vehicle_sub_model, prefix: true
end