Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Defining foreign key relationships for Rails' models

I have a Comment class with a :foreign_key of post_id in the Post class.

class Comment < ActiveRecord::Base   belongs_to :post, :class_name => "Post", :foreign_key => "post_id", :counter_cache => true   belongs_to :author, :class_name => "User", :foreign_key => "author_id" end 

But my CreateComments migration does not define a database-level foreign key:

class CreateComments < ActiveRecord::Migration   def self.up     create_table :comments do |t|       t.column "post_id",       :integer,   :default => 0, :null => false       t.column "author",        :string,    :default => "",   :limit => 25, :null => false       t.column "author_email",  :string,    :default => "",   :limit => 50, :null => false       t.column "content",       :text,      :null => false       t.column "status",        :string,    :default => "",   :limit => 25, :null => false       t.timestamps     end   end    def self.down     drop_table :comments   end end 

Instead post_id is a simple Integer column.

So, it seems that this foreign key relationship exists only in the mind of Rails, not at the database level.

Is this correct?

Also, is it necessary for the corresponding Post model to also declare its reciprocal foreign key relationship with Comments using the :foreign_key attribute or could that be omitted?

class Post < ActiveRecord::Base   set_table_name("blog_posts")   belongs_to :author, :class_name => "User", :foreign_key => 'author_id'   has_many :comments, :class_name => "Comment",     :foreign_key => 'post_id', :order => "created_at desc", :dependent => :destroy   has_many :categorizations   has_many :categories, :through => :categorizations   named_scope :recent, :order => "created_at desc", :limit => 5  end 
like image 313
pez_dispenser Avatar asked May 24 '09 18:05

pez_dispenser


People also ask

What is difference between Has_one and Belongs_to?

They essentially do the same thing, the only difference is what side of the relationship you are on. If a User has a Profile , then in the User class you'd have has_one :profile and in the Profile class you'd have belongs_to :user .

Do you need foreign keys in Rails?

You do not need a foreign key constraints for ActiveRecord to correctly map the relationships. You can use validations to have the Rails app ensure data integrity.

What is Active Record in Ruby on Rails?

Active Record is the M in MVC - the model - which is the layer of the system responsible for representing business data and logic. Active Record facilitates the creation and use of business objects whose data requires persistent storage to a database.


1 Answers

The Rails default behaviour is that the column used to hold the foreign key on a model is the name of the association with the suffix _id added. The :foreign_key option lets you set the name of the foreign key directly. The associations between your Post and Comment model classes should look like this:

class Post < ActiveRecord::Base   has_many :comments end  class Comment < ActiveRecord::Base   belongs_to :post end 

—Note that you don't need :class_name => "Post" in your Comment model. Rails already has that information. You should only be specifying :class_name and :foreign_key when you need to override the Rails' conventions.

You're correct that Rails maintains the foreign key relationships for you. You can enforce them in the database layer if you want by adding foreign key constraints.

  • I think you would benefit from reading A Guide to ActiveRecord Associations.
like image 182
John Topley Avatar answered Oct 08 '22 11:10

John Topley