2009-05-24 106 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为你维护外键关系是正确的。如果您想添加外键约束,您可以在数据库层中强制执行它们。