简体   繁体   English

Rails 关联 - has_many =>:through - 但相同的 model

[英]Rails Associations - has_many => :through - but same model

What I am trying to do:我正在尝试做的事情:

I have a blog and want to show related posts below the main post.我有一个博客,想在主帖下方显示相关帖子。

class Post < ActiveRecord::Base

  has_many :related_posts
  has_many :posts, :through => :related_posts

end

And then in the join model/table然后在连接模型/表中

class RelatedPost < ActiveRecord::Base

  belongs_to :post

end

And of course there is a table called related_posts with two post_id columns.当然,还有一个名为related_posts的表,其中包含两个post_id列。

Obviously there are several flaws with this, I'm just not sure how to make this association work in Rails.显然这有几个缺陷,我只是不确定如何使这个关联在 Rails 中工作。

That was an interesting question.这是一个有趣的问题。

I just created a working app for your use case.我刚刚为您的用例创建了一个工作应用程序。

post.related_posts will give you all posts related from post, while post.inverse_related_posts will give you all posts related to post. post.related_posts 将为您提供与 post 相关的所有帖子,而 post.inverse_related_posts 将为您提供与 post 相关的所有帖子。

Here's what my models look like:这是我的模型的样子:

class Post < ActiveRecord::Base
  has_many :related_posts_association, :class_name => "RelatedPost"
  has_many :related_posts, :through => :related_posts_association, :source => :related_post
  has_many :inverse_related_posts_association, :class_name => "RelatedPost", :foreign_key => "related_post_id"
  has_many :inverse_related_posts, :through => :inverse_related_posts_association, :source => :post
end

class RelatedPost < ActiveRecord::Base
  belongs_to :post
  belongs_to :related_post, :class_name => "Post"
end

My schema:我的架构:

ActiveRecord::Schema.define(:version => 20110702194300) do

  create_table "posts", :force => true do |t|
    t.string   "name"
    t.datetime "created_at"
    t.datetime "updated_at"
  end

  create_table "related_posts", :force => true do |t|
    t.integer  "post_id"
    t.integer  "related_post_id"
    t.datetime "created_at"
    t.datetime "updated_at"
  end

end

Here's a dump of a console session that demonstrating the relationship.这是一个控制台 session 的转储,它展示了这种关系。

ruby-1.9.2-p180:001:0>> p = Post.create! name: "Hello"
  SQL (23.5ms)  INSERT INTO "posts" ("created_at", "name", "updated_at") VALUES (?, ?, ?)  [["created_at", Sat, 02 Jul 2011 20:03:43 UTC +00:00], ["name", "Hello"], ["updated_at", Sat, 02 Jul 2011 20:03:43 UTC +00:00]]
# => #<Post id: 1, name: "Hello", created_at: "2011-07-02 20:03:43", updated_at: "2011-07-02 20:03:43">
ruby-1.9.2-p180:002:0>> p2 = Post.create! name: "World"
  SQL (1.0ms)  INSERT INTO "posts" ("created_at", "name", "updated_at") VALUES (?, ?, ?)  [["created_at", Sat, 02 Jul 2011 20:03:48 UTC +00:00], ["name", "World"], ["updated_at", Sat, 02 Jul 2011 20:03:48 UTC +00:00]]
# => #<Post id: 2, name: "World", created_at: "2011-07-02 20:03:48", updated_at: "2011-07-02 20:03:48">
ruby-1.9.2-p180:003:0>> p.related_posts
  Post Load (0.2ms)  SELECT "posts".* FROM "posts" INNER JOIN "related_posts" ON "posts"."id" = "related_posts"."related_post_id" WHERE "related_posts"."post_id" = 1
# => []
ruby-1.9.2-p180:004:0>> p2.related_posts
  Post Load (0.4ms)  SELECT "posts".* FROM "posts" INNER JOIN "related_posts" ON "posts"."id" = "related_posts"."related_post_id" WHERE "related_posts"."post_id" = 2
# => []
ruby-1.9.2-p180:005:0>> p.related_posts << p2
  SQL (0.7ms)  INSERT INTO "related_posts" ("created_at", "post_id", "related_post_id", "updated_at") VALUES (?, ?, ?, ?)  [["created_at", Sat, 02 Jul 2011 20:04:01 UTC +00:00], ["post_id", 1], ["related_post_id", 2], ["updated_at", Sat, 02 Jul 2011 20:04:01 UTC +00:00]]
# => [#<Post id: 2, name: "World", created_at: "2011-07-02 20:03:48", updated_at: "2011-07-02 20:03:48">]
ruby-1.9.2-p180:006:0>> RelatedPost.all
  RelatedPost Load (0.4ms)  SELECT "related_posts".* FROM "related_posts" 
# => [#<RelatedPost id: 1, post_id: 1, related_post_id: 2, created_at: "2011-07-02 20:04:01", updated_at: "2011-07-02 20:04:01">]
ruby-1.9.2-p180:007:0>> p2.inverse_related_posts
  Post Load (0.2ms)  SELECT "posts".* FROM "posts" INNER JOIN "related_posts" ON "posts"."id" = "related_posts"."post_id" WHERE "related_posts"."related_post_id" = 2
# => [#<Post id: 1, name: "Hello", created_at: "2011-07-02 20:03:43", updated_at: "2011-07-02 20:03:43">]
ruby-1.9.2-p180:008:0>> p = Post.first
  Post Load (0.5ms)  SELECT "posts".* FROM "posts" LIMIT 1
# => #<Post id: 1, name: "Hello", created_at: "2011-07-02 20:03:43", updated_at: "2011-07-02 20:03:43">
ruby-1.9.2-p180:009:0>> p2.related_posts << p
  SQL (25.7ms)  INSERT INTO "related_posts" ("created_at", "post_id", "related_post_id", "updated_at") VALUES (?, ?, ?, ?)  [["created_at", Sat, 02 Jul 2011 20:05:29 UTC +00:00], ["post_id", 2], ["related_post_id", 1], ["updated_at", Sat, 02 Jul 2011 20:05:29 UTC +00:00]]
  Post Load (0.3ms)  SELECT "posts".* FROM "posts" INNER JOIN "related_posts" ON "posts"."id" = "related_posts"."related_post_id" WHERE "related_posts"."post_id" = 2
# => [#<Post id: 1, name: "Hello", created_at: "2011-07-02 20:03:43", updated_at: "2011-07-02 20:03:43">]
ruby-1.9.2-p180:010:0>> p2.related_posts
# => [#<Post id: 1, name: "Hello", created_at: "2011-07-02 20:03:43", updated_at: "2011-07-02 20:03:43">]
ruby-1.9.2-p180:011:0>> exit


Loading development environment (Rails 3.1.0.rc4)
ruby-1.9.2-p180:001:0>> Post.first.related_posts
  Post Load (0.3ms)  SELECT "posts".* FROM "posts" LIMIT 1
  Post Load (0.2ms)  SELECT "posts".* FROM "posts" INNER JOIN "related_posts" ON "posts"."id" = "related_posts"."related_post_id" WHERE "related_posts"."post_id" = 1
# => [#<Post id: 2, name: "World", created_at: "2011-07-02 20:03:48", updated_at: "2011-07-02 20:03:48">]
ruby-1.9.2-p180:002:0>> Post.last.related_posts
  Post Load (0.2ms)  SELECT "posts".* FROM "posts" ORDER BY "posts"."id" DESC LIMIT 1
  Post Load (0.2ms)  SELECT "posts".* FROM "posts" INNER JOIN "related_posts" ON "posts"."id" = "related_posts"."related_post_id" WHERE "related_posts"."post_id" = 2
# => [#<Post id: 1, name: "Hello", created_at: "2011-07-02 20:03:43", updated_at: "2011-07-02 20:03:43">]

You're looking for self referential association.您正在寻找自我参照关联。

I suggest you take inspiration here.我建议你在这里汲取灵感。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM