为Rails的模型定义外键关系

pez*_*ser 53 ruby-on-rails foreign-keys

我在Post类中有一个带有:foreign_key of post_id的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
Run Code Online (Sandbox Code Playgroud)

但是我的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
Run Code Online (Sandbox Code Playgroud)

相反,post_id是一个简单的Integer列.

因此,似乎这种外键关系只存在于Rails的头脑中,而不是存在于数据库级别.

它是否正确?

此外,相应的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
Run Code Online (Sandbox Code Playgroud)

Joh*_*ley 75

Rails的默认行为是用于在模型上保存外键的列是_id添加了后缀的关联的名称.该:foreign_key选项允许您直接设置外键的名称.您PostComment模型类之间的关联应如下所示:

class Post < ActiveRecord::Base
  has_many :comments
end

class Comment < ActiveRecord::Base
  belongs_to :post
end
Run Code Online (Sandbox Code Playgroud)

- 注意您:class_name => "Post"Comment模型中不需要.Rails已经掌握了这些信息.您应该只指定:class_name,:foreign_key何时需要覆盖Rails的约定.

你是正确的,Rails为你维护外键关系.如果需要,可以通过添加外键约束来在数据库层中强制实施它们.

  • 如果您还想删除关联的列。您需要在编写关联的行末尾添加“dependent:destroy”。 (2认同)