Here's the documentation.
Let's say we have this:
class Image
belongs_to :user
end
- Always singular!
belongs_to :user
, notbelongs_to :users
- Double check, it's the #1 error students make with this.
- Goes on the model with a foreign key, so
belongs_to :user
means thatImage
has auser_id
column - Adds
user
anduser=
instance methods (among others), to get and set the associated user - Assumes that the foreign key is
user_id
, i.e.Image
has auser_id
column.belongs_to :thing
would assume athing_id
column, and so on. - Assumes that the associated class is
User
, i.e. it should doUser.find
notWombat.find
or something.
Let's say Image
has an associated User
, but the foreign key isn't user_id
,
it's owner_id
. We'd use the foreign_key
option. Note that we still want a
User
instance when we call image.user
, we're only changing the column name.
belongs_to :user, foreign_key :owner_id
OK, now let's assume that Image
has a user_id
column (like belongs_to :user
implies), but we want to get a Wombat
instance when we call
image.user
. We'd use the class_name
option:
# "Wombat" has to be a string.
belongs_to :user, class_name: "Wombat"
You can combine the options if you need to, as well.
Here's the documentation.
Let's say we have this:
class User
has_many :images
end
- Always plural!
has_many :images
, nothas_many :image
- Does not have the foreign key; the other side of the relation has the foreign key (here, it's images).
- Assumes that the images table has a an
association_id
column. Here, the association isuser
, so it looks foruser_id
.- Remember,
user.images
translates to the SQLSELECT * FROM images WHERE user_id = N
, where N isuser.id
.
- Remember,
- Assumes that it will return
Image
instances
Let's say that Image
has an owner_id
foreign key instead of user_id
. So
the SQL that has to be generated is (N is the user's ID):
SELECT * FROM images WHERE product_id = N
-- Instead of:
-- SELECT * FROM images WHERE user_id = N
In order for Rails to use the association correctly, you'd do:
has_many :images, foreign_key: :product_id
OK, now let's say that we want to find SpecialImage
s, not Image
s, but still call user.images
.
SpecialImage
has a user_id
foreign key, so we don't need the foreign_key
option, but has_many :images
will look for an Image
class. To have it look
for SpecialImage
s instead:
# Note that `class_name` uses a string, it's just how it is.
has_many :images, class_name: "SpecialImage"