through references rails many has_one has_many has_and_belongs_to_many has example belongs and ruby-on-rails associations has-many-through

ruby-on-rails - references - rails has_one through



Rails Associations-has_many=>: a través de-pero el mismo modelo (2)

Lo que estoy tratando de hacer:

Tengo un blog y quiero mostrar publicaciones relacionadas debajo de la publicación principal.

class Post < ActiveRecord::Base has_many :related_posts has_many :posts, :through => :related_posts end

Y luego en el modelo / tabla de unión

class RelatedPost < ActiveRecord::Base belongs_to :post end

Y, por supuesto, hay una tabla llamada related_posts con dos columnas post_id .

Obviamente hay varios defectos con esto, no estoy seguro de cómo hacer que esta asociación funcione en Rails.


Esa fue una pregunta interesante.

Acabo de crear una aplicación que funcione para su caso de uso.

post.related_posts te dará todas las publicaciones relacionadas desde la publicación, mientras que post.inverse_related_posts te proporcionará todas las publicaciones relacionadas con la publicación.

Así es como se ven mis modelos:

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

Mi esquema:

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

Aquí hay un volcado de una sesión de consola que demuestra la relación.

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">]


Está buscando una asociación autorreferencial.

Te sugiero que te inspires here.