【问题标题】:Defining foreign key relationships for Rails' models为 Rails 模型定义外键关系
【发布时间】:2010-10-28 14:42:35
【问题描述】:

我在 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

但我的 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 属性声明其与 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

【问题讨论】:

  • 我和你一样惊讶的是 Rails 不使用 SQL 外键。这使得在 DB 上使用非 Rails 工具变得很困难。
  • Rails 遵循“所有业务逻辑都应在应用程序中定义”的约定......因此它仅将 DB 用作“哑”存储。没有外键,没有存储过程,没有约束(例如在 postgres 中支持)。编辑:刚刚发现这个答案是一样的 - stackoverflow.com/questions/8334602/…

标签: ruby-on-rails foreign-keys


【解决方案1】:

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

class Post < ActiveRecord::Base
  has_many :comments
end

class Comment < ActiveRecord::Base
  belongs_to :post
end

- 请注意,您的 Comment 模型中不需要 :class_name =&gt; "Post"。 Rails 已经有了这些信息。只有在需要覆盖 Rails 的约定时,才应该指定 :class_name:foreign_key

Rails 为您维护外键关系是正确的。如果需要,可以通过添加外键约束在数据库层强制执行它们。

【讨论】:

  • 因为 foreign_key 连接不在数据库级别,仅在 rails 中。如果从 Post 中删除一条记录,它在评论中的关联行是否也会被删除?这是维护foreign_key 的另一个好处。我会得到这个好处吗?
  • 如果您也想删除关联的列。您需要在您编写关联的行末尾添加dependent:destroy
猜你喜欢
  • 2021-10-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多