2009-05-24 155 views
48

我在Post類中有一個帶有:post_id的foreign_key的Comment類。定義Rails模型的外鍵關係

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 

但我CreateComments遷移沒有定義數據庫級別的外鍵:

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 

相反POST_ID是一個簡單的整數列。

因此,這種外鍵關係似乎只存在於Rails的思想中,而不是在數據庫級別。

這是正確的嗎?

此外,相應的Post模型是否也需要使用:foreign_key屬性聲明其相互的外鍵關係,或者可以省略?

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 
+0

我分享你的驚喜,Rails不使用SQL外鍵。這使得在DB上使用非導軌工具變得很困難。 – Greg 2012-09-20 19:58:55

+2

Rails遵循「應該在應用程序中定義所有業務邏輯」的約定......所以它僅將DB用作「啞」存儲。沒有外鍵,沒有存儲過程,沒有限制(例如在postgres中支持)。編輯:剛纔發現這個答案說同樣 - http://stackoverflow.com/questions/8334602/need-to-create-a-foreign-key-when-creating-a-table-on-rails – 2013-03-31 18:02:39

回答

69

Rails的默認行爲是用來存放在模型外鍵的列後綴_id加入協會的名稱。 :foreign_key選項可讓您直接設置外鍵的名稱。您PostComment模型類之間的關聯應該是這樣的:

class Post < ActiveRecord::Base 
    has_many :comments 
end 

class Comment < ActiveRecord::Base 
    belongs_to :post 
end 

—注意不要在你的Comment模型需要:class_name => "Post"。 Rails已經有了這些信息。當你需要重寫Rails的約定時,你應該只指定:class_name:foreign_key

Rails爲你維護外鍵關係是正確的。如果您想添加外鍵約束,您可以在數據庫層中強制執行它們。