【发布时间】: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