【问题标题】:How to write this ActiveRecord Query using Join instead of subquery in Rails 4如何在 Rails 4 中使用 Join 而不是子查询来编写这个 ActiveRecord 查询
【发布时间】:2014-06-30 14:32:24
【问题描述】:

考虑以下几点:

class User < ActiveRecord::Base
  has_many :events
end

class Event < ActiveRecord::Base
  belongs_to :user #this user is the event owner
  has_many :members
end

class Members < ActiveRecord::Base
  belongs_to :user
  belongs_to :event
end

现在,我需要列出current_user 为其所有者的所有成员。所以我想出了这个:

@members = Member.where event_id: current_user.events

产生以下查询:

SELECT "members".* FROM "members" WHERE "members"."event_id" IN (SELECT "events"."id" FROM "events" WHERE "events"."user_id" = 1)

这按预期工作,但使用子查询而不是JOIN。有谁知道编写相同查询的更好方法?

【问题讨论】:

    标签: sql ruby-on-rails postgresql activerecord ruby-on-rails-4


    【解决方案1】:

    添加一个 has_many :through 关联到您的用户模型:

    class User < ActiveRecord::Base
      has_many :events
      has_many :members, :through => :events
    end
    

    现在您可以通过成员关联查询一个用户的所有成员:

    user.members
    

    生成的 SQL 如下所示:

    SELECT "members".* FROM "members" INNER JOIN "events" ON "members"."id" = "events"."member_id" WHERE "events"."user_id" = 1
    

    【讨论】:

      【解决方案2】:

      转换为 JOIN 语法(使用表别名使其更短且更易于阅读):

      SELECT m.*
      FROM   events e
      JOIN   members m ON m.event_id = e.id
      WHERE  e.user_id = $1
      

      【讨论】:

      • 我怎样才能使用ActiveRecord生成这个?
      【解决方案3】:

      我想这会奏效。

      Member.joins(:event).where("events.user_id = ?" , current_user.id)
      

      【讨论】:

        【解决方案4】:

        你可以这样做:

        Member.joins(:event).where(events: {user_id: current_user.id})
        

        【讨论】:

          猜你喜欢
          • 2021-10-21
          • 2017-07-26
          • 2015-09-04
          • 1970-01-01
          • 1970-01-01
          • 2018-08-19
          • 2017-08-04
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多