使用三向关联/has_many进行查询:through/join



我正在使用可用的指南/api/books自学Rails,但我很难理解使用三向/嵌套has_many的联接:通过关联。

我有用户连接:通过会员资格

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

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

例如。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#索引

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-表,但就我所见,没有一个例子适用。

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

我相信这就是您想要的:

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

另请参阅:具有多个的过滤器模型具有多个通过(不完全相同,但相似)

感谢@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

最新更新