On Feb 5, 10:29 am, Mike
<mailmikes...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
wrote:> 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?
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.
> 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'' )
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 Jones
--
You received this message because you are subscribed to the Google Groups
"Ruby on Rails: Talk" group.
To post to this group, send email to
rubyonrails-talk-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org
To unsubscribe from this group, send email to
rubyonrails-talk+unsubscribe@googlegroups.com.
For more options, visit this group at
http://groups.google.com/group/rubyonrails-talk?hl=en.