【问题标题】:Complex JOIN with ActiveRecord and Rails 3使用 ActiveRecord 和 Rails 3 进行复杂的 JOIN
【发布时间】:2019-11-23 01:13:50
【问题描述】:

我有以下型号:

class User < ActiveRecord::Base
  has_many :memberships
  has_many :groups, :through => :memberships
end

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

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

class Post < ActiveRecord::Base
  belongs_to :group
end

我必须找到属于用户所属组的所有帖子。我用这种方法做到了:

@post = Post
  .joins(:group => {:memberships => :user})
  .where(:memberships => {:user_id => current_user.id})

但它会产生低效的 SQL:

SELECT "posts".* FROM "posts" 
INNER JOIN "groups" ON "groups"."id" = "posts"."group_id" 
INNER JOIN "memberships" ON "memberships"."group_id" = "groups"."id" 
INNER JOIN "users" ON "users"."id" = "memberships"."user_id" 
WHERE "memberships"."user_id" = 1

我想进行这样的查询:

SELECT posts.* FROM posts 
INNER JOIN memberships ON memberships.group_id = posts.group_id 
WHERE memberships.user_id = 1

如何在不使用原始 SQL 的情况下做到这一点?

【问题讨论】:

    标签: sql ruby-on-rails ruby-on-rails-3 activerecord join


    【解决方案1】:

    你可以在不改变你的模型的情况下更接近,通过从你的通话中删除未使用的加入:

    Post.joins(group: :memberships).where(memberships: { user_id: 1 })
    

    编译成 SQL

    SELECT "posts".* FROM "posts"
    INNER JOIN "groups" ON "groups"."id" = "posts"."group_id"
    INNER JOIN "memberships" ON "memberships"."group_id" = "groups"."id" 
    WHERE ("memberships"."user_id" = 1)
    

    【讨论】:

      【解决方案2】:

      这样的东西应该适合你,尽管它需要混合一些原始 SQL

      Post
        .joins("INNER JOIN memberships ON memberships.group_id = posts.group_id")
        .where(:memberships => {:user_id => current_user.id})
      

      【讨论】:

      • 如何从组表中选择特定列?
      猜你喜欢
      • 2011-12-22
      • 1970-01-01
      • 2012-07-19
      • 1970-01-01
      • 1970-01-01
      • 2015-02-05
      • 2011-09-26
      • 1970-01-01
      • 2010-12-03
      相关资源
      最近更新 更多