HABTM and has_one with STL

Hi,

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

This way, I could do something like so:

car = Car.new
car.wheels << Wheel.new( :brand => ‘Dunlop’)
car.wheels << Wheel.new( :brand => ‘Dunlop’)
car.wheels << Wheel.new( :brand => ‘Bridgestone’ )
car.wheels << Wheel.new( :brand => ‘Bridgestone’ )
car.steering_wheel = SteeringWheel.new( :brand => ‘Sparco’ )

On Feb 5, 10:29am, Mike [email protected] wrote:

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 = Car.new
car2 = Car.new
wheel = Wheel.new(:brand => ‘Foo’)
steering_wheel = SteeringWheel.new(:brand => ‘Bar’)

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

so no problems there

car1.steering_wheel = steering_wheel
car1.save
car2.steering_wheel = steering_wheel
car2.save

and the gotcha:

car1.reload
car1.steering_wheel # => nil


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.

| Privacy Policy | Terms of Service | Remote Ruby Jobs