【问题标题】:Understanding Rails ActiveRecord "single model" self joins了解 Rails ActiveRecord“单一模型”自连接
【发布时间】:2012-03-04 06:11:34
【问题描述】:

我很难理解如何在 Rails 中实现单个模型自联接。 Guide to ActiveRecord Associations section 2.10 简要解释了 Self-Joins,但没有提供足够的信息,并且关于此的每个示例或帖子都引用了非单一模型 self-join 的 Friendly Friend Railcast 示例,如 Rails Guide section 2.10 中所述。

这个想法是一个模型本身 has_many 和 belongs_to,不需要单独的关系表。我看到需要单独表的唯一原因是,如果您希望关系包含更多信息而不仅仅是关系。例如“最好的朋友”,“几乎不认识他们”

我有一个简单的 Post 架构:

create_table "posts", :force => true do |t|
    t.datetime "posted"
    t.string   "nick"
    t.string   "title"
    t.text     "content"
    t.integer  "parent_post_id"
    t.datetime "created_at",     :null => false
    t.datetime "updated_at",     :null => false
end

parent_post_id 是对其他 Post post_id 的自我引用。 posts.rb 模型定义了关系:

class Post < ActiveRecord::Base
  has_many :replies, :class_name => "Post"
  belongs_to :parent_post, :class_name => "Post",
    :foreign_key => "parent_post_id"
end

在控制器或视图中,我希望能够做这样的事情:

@posts.each do |post|
  ...
  @replies = post.replies
  @replies.each do |reply|
    ...
  end
end

或查找帖子的父级:

@parent_post = post.parent_post

这可能都是一些语法误解。所以提前感谢任何可以给我一些理智的人。我浏览了所有 SO 和博客文章,没有人尝试过指南中描述的单一模型自引用自联接方法。

任何人提供的解释没有指向使用单独关系表的Friendly Friend示例。

【问题讨论】:

  • 如果您按照预期的方式描述发生/未发生的事情,会更容易开始。另外,act_as_tree 之类的东西是单表、单模型的自我引用——你有没有考虑过类似的东西?
  • 我以为我做到了。我期望能够调用 post.replies 并获得一组基于父帖子填充的 Post 实例,它的 parent_post_id = post_id。
  • 这解释了你做了什么。不是发生了什么。
  • 很抱歉。 post.replies 抛出了一个 SQL 错误。请看下面我的回答。该错误是一个 SQL 错误,最终让我知道了问题所在。 post.replies 正在生成 SQL,其中 :replies 字段键默认为 post_id。不是我想要的 parent_post_id 。一旦我将 :foreign_key 添加到 :replies,现在 post.replies 将查询使用 parent_post_id 的帖子。

标签: ruby-on-rails-3 activerecord


【解决方案1】:

我缺少“parent_post_id”的 has_many 外键。设置后,post.replies 将通过 parent_post_id 引用其他 Post 实例。

posts.rb 模型定义了关系:

class Post < ActiveRecord::Base
  has_many :replies, :class_name => "Post",
    :foreign_key => "parent_post_id"
  belongs_to :parent_post, :class_name => "Post",
    :foreign_key => "parent_post_id"
end

我现在可以创建帖子,将 parent_post_id 分配给不同的帖子,然后获取所有回复任何父帖子的帖子。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-10-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多