Every once in a while, I pipe up and whine that “belongs_to” should
really
be 'refers_to" [http://dev.rubyonrails.org/ticket/2130]. It’s time
again.
I’ve got a bunch of stuff going onto eBay, so, like any good engineer, I
don’t just post it manually: I design a Rails-based inventory database
that
creates a semantically-correct XHTML/CSS auction posting with a variable
number of thumbnails (stored with file_column) and Textile fields.
I start out with
class Item < ActiveRecord::Base
:has_many :pictures
end class
But I want one of those pictures to be featured as the gallery photo.
So,
naturally, I gravitate towards adding
class Item < ActiveRecord::Base
:has_one primary_picture, :class_name => ‘Picture’
end
I am encouraged in this futile pursuit by the docs, which I quickly skim
to
see things like
:has_one :last_comment, :class_name => “Comment”, :order =>
“posted_on”
Of course, in the light of day, it’s clear that this automagically
creates
the last_comment association by picking the most recent comment. But at
3am, it just reinforced the tendency to use has_one. Ditto the many
other
has_one examples I found - half of which used the automatic-first-record
feature, and half of which were probably just making the same mistake I
was.
I started getting nil objects, and was mystified until I finally tried
explicitly setting the foreign key:
:has_one primary_picture, :class_name => ‘Picture’,
:foreign_key => ‘primary_picture_id’
at which point Rails helpfully told me that there was no
Picture.primary_picture_id field. Then I remembered for the umpteenth
time
that has_one is for the record that does NOT have the foreign key, and
belongs_to is for the one that does, and I should not be misled by the
semantics of the actual has_one and belongs_to keywords.
Item :belongs_to primary_picture makes no sense. Item :refers_to
primary_picture does. This is way too small for even a plugin - and I
don’t think that type of syntax change belongs in a plugin, anyway. I
have
yet to hear anyone who’s opposed to it… can’t we PLEASE add this alias
and consider deprecating belongs_to over time? It’s… just… wrong.
Jay L.