Polymorphic associations, wrong use?


I would like to populate dropdown list with values from two different
models. My first idea was to create a polymorphic association. But
then I got stuck with the code for a dropdown list. How to make it
return object_id and object_type?

Here are my models:

card.rb -----------------------------------------------
class Card < ActiveRecord::Base
  belongs_to :vehicle, :polymorphic => true

No, wouldn't work, since a car and a boat can have the same id.

You can though use something like name and car_id or boat_id
as identifier (like car_123 and boat_123)
Then in you controller params[:id] (or whatever) would contain that
and you could use some string functions to split at the _ the
type and id

This is a good example of one of the problems with the polymorphic
model as it is commonly implemented (not only in Rails solutions).
String functions to split the type and id? Frankly, that is a kludge
that is going to lead to interesting issues as you try to do more with
your data. I'd suggest you consider that your underlying logical model
is not correct for your requirements. Try modeling Car and Boat as
subtypes of Vehicle, which would be the supertype. A Card would then
have vehicle_id as a foreign key (unless cards can belong to more than
one vehicle, in which case you need a join model between Vehicle and
Card). At the implementation level, Vehicle could have a database
table (and model) of its own. The Cars and Boats tables would then
each have vehicle_id as a foreign key. You would also be able to use
foreign key constraints in Cars and Boats to help ensure the integrity
of your data - the polymorphic association method Rails uses does not
allow for these constraints, which is a serious problem unless you
don't need to worry about the reliability of the data in your database
(but if you can't rely on the integrity of the data, what use is your
database?). For more information, see "Case*Method: Entity
Relationship Modelling" by Richard Barker:

STI better suits what you're asking about doing:


What "better suits" can only be determined by a proper analysis of the
business requirements. It might appear to solve the one issue that has
been presented here, but is it the appropriate solution in the wider
context of the whole system? The supertype-subtype model I suggested
as a *possibility* is a well-known pattern that can be used in
situations like this.

Single-Table Inheritance will result in a table with lots of NULLs in
it. You then have the issue of ensuring that the columns for one model
are filled, while columns for other models have NULL in them. On the
subject of NULLs, see: http://www.databasedesign-resource.com/null-values-in-a-database.html

If you decide STI is appropriate for your needs, this might help get
you started: http://rookieonrails.blogspot.com/2008/01/single-table-inheritance-in-rails.html
Or see the Agile Web Development with Rails book, of course.