【问题标题】:Query with three way association / has_many :through / join使用三路关联查询/has_many :through/join
【发布时间】:2012-11-27 23:36:52
【问题描述】:

我正在使用可用的指南/api/书籍自学 Rails,但我无法理解与三路/嵌套 has_many 的连接:通过关联。

我有用户群组:通过会员联系。

我也有 postsgroups 的多对多。同一个帖子可以发布到多个群组 + 群组可以有多个帖子。

我希望能够为用户的主页显示的所有不同的帖子,用户是其中的成员。

例如。 current_user.groups.posts # 真希望这么简单!!

这是我的代码。

Models:

class User < ActiveRecord::Base
  has_many :memberships
  has_many :groups, :through => :memberships
  has_many :posts  # as author of post
end

class Group < ActiveRecord::Base
  has_many :memberships
  has_many :users, :through => :memberships
  has_and_belongs_to_many :posts
end

class Membership < ActiveRecord::Base
  belongs_to :user
  belongs_to :group
end

class Post < ActiveRecord::Base
  belongs_to :user
  has_and_belongs_to_many :groups
end

routes.rb

Myapp::Application.routes.draw do
  get "admin/index"
  devise_for :users

  resources :users do
    member do
      get :groups
    end
  end

  resources :groups do
    member do
      get :members
      post :join
      post :leave
    end
  end

  resources :posts

home_controller.rb#index

class HomeController < ApplicationController
  before_filter :authenticate_user!

  def index
    @user = current_user
    @groups = Group.all
    @user_groups = @user.groups
    @home_page_posts = Post.joins(:groups, :user)
  end
end

这显然只是给了我所有组中所有帖子的不明确列表。

如果有人能指出我正确的方向。 我已经尝试过http://guides.rubyonrails.org/active_record_querying.html#joining-tables,但据我所知,这些示例都不适用。

如果您需要我提供更多信息,请告诉我。:D

【问题讨论】:

    标签: join ruby-on-rails-3.2 has-many-through


    【解决方案1】:

    我相信这就是你想要的:

    Post.includes(:groups => :users).where('users.id' => current_user.id)
    

    这将生成这样的 SQL(对于 current_user.id = 1):

    SELECT "posts"."id" AS t0_r0, "posts"."user_id" AS t0_r1,
      "posts"."created_at" AS t0_r2, "posts"."updated_at" AS t0_r3,
      "groups"."id" AS t1_r0, "groups"."created_at" AS t1_r1,
      "groups"."updated_at" AS t1_r2, "users"."id" AS t2_r0,
      "users"."name" AS t2_r1, "users"."created_at" AS t2_r2,
      "users"."updated_at" AS t2_r3
      FROM "posts"
      LEFT OUTER JOIN "groups_posts" ON "groups_posts"."post_id" = "posts"."id"
      LEFT OUTER JOIN "groups" ON "groups"."id" = "groups_posts"."group_id"
      LEFT OUTER JOIN "memberships" ON "memberships"."group_id" = "groups"."id"
      LEFT OUTER JOIN "users" ON "users"."id" = "memberships"."user_id"
      WHERE "users"."id" = 1
    

    另见:Filter model with multiple has many through(不完全相同,但相似)

    【讨论】:

    • 非常感谢!!!这完全符合我的需要。看来我需要了解有关过滤器的更多信息。再次感谢!
    【解决方案2】:

    感谢@shioyama,我最终使用他的答案为 Post 创建了一个模型方法:

    def self.posts_for_users_groups(current_user)
      includes(:groups => :users).where('users.id' => current_user.id)
    end
    

    我从我的家庭控制器调用:

    def index
      @user_visible_posts = Post.posts_for_users_groups(current_user)
    end
    

    再次感谢@shioyama:D

    【讨论】:

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