I'm relatively new to Ruby on Rails and I'm trying to understand the way how active record associations work. So far, I thought I figured it out, but not sure anymore.
Anyway, I'm building my very own CMS and apart from all, I'll focus on my main problem. I'm having a table pages and pictures:
class CreatePages < ActiveRecord::Migration
def change
create_table :pages do |t|
t.string :name
t.integer :headline_image_id
t.timestamps
end
create_table :pictures do |t|
t.string :name
t.string :description
t.string :image
t.timestamps
end
end
end
With this I have my models:
class Page < ActiveRecord::Base
validates :name, presence: true
validates :headline_image_id, presence: true
belongs_to :headline_image, class_name: Picture, foreign_key: :headline_image_id
end
class Picture < ActiveRecord::Base
mount_uploader :image, ImageUploader
end
And that's it. Now after I create a picture and a page which has the id of a picture in the headline_image_id attribute, I can fetch that headline_image with @target_page.headline_image. Perfect, but the thing that is bothering me is the readability of the code. Wouldn't it make much more sense if I associated the two models in the Page model like this:
class Page < ActiveRecord::Base
validates :name, presence: true
validates :headline_image_id, presence: true
has_one :headline_image, class_name: Picture, foreign_key: :headline_image_id
end
If I do it like this and run @target_page.headline_image I get a SQL Constraint exception that tells me there is no headline_image_id in the pictures table.
I read all the Active Record Association tutorial on Ruby on Rails Guides and watched all the codeschool Rails courses, and I was pretty sure that everything was going to work with a has_one association...but it didn't.
Can someone please explain? Thanks!
Rails Guides provides an explanation as to why you're experiencing the problem. Essentially, when you declare a
belongs_to
relationship, the foreign key appears on the table for the class declaring it. When you declare ahas_one
relationship, the foreign key is on the table for the class in the declaration.Example
In this scenario, the
pictures
table would require apage_id
foreign key.In this scenario, the
pages
table would require apicture_id
foreign key.If you wanted to use a
has_one
association, just remove theheadline_image_id
column from yourpages
table and add apage_id
column to yourpictures
table. You can do this in one migration. After you run the migration, change your model definitions as per my above example. Hope this helps.