I have an interesting dilemma, which is best shown through example.
Say I have Car and Part models which have a HABTM association. In
this case though, the Part class is an STL with Wheel and
SteeringWheel as models. Is there a way to setup the Car model with
both HABTM and has_one relationships to the same table?
class Part < ActiveRecord::Base
has_and_belongs_to_many :cars
end
class Wheel < Part
end
class SteeringWheel < Part
do I put a new association here?
end
class Car < ActiveRecord::Base
has_and_belongs_to_many :cars
has_one :steering_wheel
end
end
class Wheel < Part
end
class SteeringWheel < Part
do I put a new association here?
You’d need to declare ‘belongs_to :car’ and add a corresponding car_id
field to the parts table.
end
class Car < ActiveRecord::Base
has_and_belongs_to_many :cars
I’m guessing this is a typo, as you’ve got it as ‘wheels’ below.
car.steering_wheel = SteeringWheel.new( :brand => ‘Sparco’ )
I’m not sure how useful the “car” analogy is here; it carries quite a
bit of semantic baggage that may not apply to your real problem
domain. Some notes about it anyways:
are the records in the ‘Part’ table intended to represent a single
instance of a particular part or the generic class of all similar
parts? It’s unclear from the example above, as every instance of Car
needs a different SteeringWheel record (has_one/belongs_to can only
link one pair of records) but Car instances can share Wheels. In code:
car1.wheels << wheel
car1.save
car2.wheels << wheel
car2.save
car1.wheels.first # => some Wheel object
car2.wheels.first # => some Wheel object with the same ID as the first
The other big issue with using STI here is that there really aren’t
that many properties in common between the two entities -
manufacturer, perhaps? There certainly aren’t many places where one
could interchangeably use a steering wheel or a regular wheel…
Again, this may be a specific issue with the “car” example, but it’s
worth checking into. If there’s some overlap but a lot of difference,
you may want to consider factoring the overlap into a module and
avoiding the “everything and the kitchen sink” table that STI can lead
to if used inappropriately.
–Matt J.
This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.