Ruby-on-rails 为 Rails 模型定义外键关系
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/904421/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Defining foreign key relationships for Rails' models
提问by pez_dispenser
I have a Comment class with a :foreign_key of post_id in the Post class.
我在 Post 类中有一个带有 post_id 的 :foreign_key 的 Comment 类。
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:
但是我的 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
Instead post_id is a simple Integer column.
而 post_id 是一个简单的整数列。
So, it seems that this foreign key relationship exists only in the mind of Rails, not at the database level.
所以,这个外键关系似乎只存在于Rails的脑海中,而不存在于数据库层面。
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?
此外,相应的 Post 模型是否有必要使用 :foreign_key 属性声明其与 Comments 的相互外键关系,或者可以省略吗?
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
回答by John Topley
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 _idadded. The :foreign_keyoption lets you set the name of the foreign key directly. The associations between your Postand Commentmodel classes should look like this:
Rails 的默认行为是模型上用于保存外键的列是_id添加后缀的关联名称。该:foreign_key选项允许您直接设置外键的名称。您的Post和Comment模型类之间的关联应如下所示:
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 Commentmodel. Rails already has that information. You should only be specifying :class_nameand :foreign_keywhen you need to override the Rails' conventions.
- 请注意:class_name => "Post",您的Comment模型中不需要。Rails 已经有了这些信息。您应该只被指定:class_name和:foreign_key当你需要重写Rails的约定。
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.
您是正确的,Rails 为您维护外键关系。如果需要,您可以通过添加外键约束在数据库层强制执行它们。
- I think you would benefit from reading A Guide to ActiveRecord Associations.
- 我认为您会从阅读ActiveRecord 关联指南中受益。

