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
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 .
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.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With