制作多级嵌套 ActiveRecord 查询的问题

Problems crafting a multi level nested ActiveRecord query

我正在 Rails 中构建一个日历应用程序。 可以邀请人们参加活动。 我在编写 @event.attending_users.

这样的查询时遇到困难

一个日历事件由一个或多个 RecurringEvents 组成。一个 RecurringEvent 有一个或多个参加者。与会者 tables 基本上是一个连接 table,它列出了正在参加 RecurringEvent 的用户。

事件

 21 class Event < ApplicationRecord
 24
 25   has_many :recurring_events, dependent: :destroy
 26   has_many :attendees, through: :reccurring_events

重复事件

 23 class RecurringEvent < ApplicationRecord
 24   has_many :comments, as: :commentable, dependent: :destroy
 25   has_many :attendees, dependent: :destroy
 26
 27   belongs_to :event

与会者

 13 class Attendee < ApplicationRecord
 14   belongs_to :recurring_event
 15   belongs_to :user
 16
 17   enum status: %w[unseen seen attending not_attending]

测试

 23 RSpec.describe Event, type: :model do
 24   before do
 25     @user = Fabricate(:user)
 26     @group = Fabricate(:group)
 27     @event = Fabricate(:event, group: @group, user: @user, recurring: :weekly)
 28   end

 49   describe "Attending" do
 50     before do
 51       @user2 = Fabricate(:user, first_name: "Second User")
 52       @group.add_member(user: @user)
 53       @event.set_user_as_attending_all(@user)
 54     end

app/models/event.rb

 43   def set_user_as_attending_all(user)
 44     return unless user.member_of? group
 45     recurring_events.each do |recurring_event|
 46       recurring_event.attend!(user)
 47     end
 48   end

要查看哪些用户正在参加活动,我正在尝试这样做:

RecurringEvent.joins(:event).where(event_id: id).joins(:attendees).where(status: "attending")

但是失败了,我不确定为什么:

*** ActiveRecord::StatementInvalid Exception: PG::InFailedSqlTransaction: ERROR:  current transaction is aborted, commands ignored until end of transaction block
: SELECT  "events".* FROM "events" ORDER BY "events"."id" DESC LIMIT 

nil
*** ActiveRecord::StatementInvalid Exception: PG::InFailedSqlTransaction: ERROR:  current transaction is aborted, commands ignored until end of transaction block
: SELECT  "recurring_events".* FROM "recurring_events" INNER JOIN "events" ON "events"."id" = "recurring_events"."event_id" INNER JOIN "attendees" ON "attendees"."recurring_event_id" = "recurring_events"."id" WHERE "recurring_events"."event_id" =  AND "recurring_events"."status" =  ORDER BY "recurring_events"."id" ASC LIMIT 

回答 1(如上问题),

RecurringEvent.joins(:event, :attendees).where('attendees.status = ?', "attending")

解释

  • 一条命令即可加入
  • 由于状态是与会者中的一列,我在状态字段前包含 table 姓名

更正 2:

下面的这个命令将return 与会者记录

Attendee.joins(recurring_event: :event).where('events.event_id = ? AND attendees.status = ?',453,2)
  • 我的建议是不要在 where 语句中直接使用数字,我在上面给出了示例
  • 自从与会者访问 recurring_event 和 recurring_event 访问事件以来,现在加入模型已更改(请参阅我上面的回答的不同之处。这意味着访问事件取决于 recurring_event

答案 3:这会给用户 table 特定事件

User.joins(attendees: [recurring_event: :event]).where('events.event_id = ? AND attendees.status = ?',453,2)
# for unique users
User.joins(attendees: [recurring_event: :event]).where('events.event_id = ? AND attendees.status = ?',453,2).uniq
  • 我的答案 2 的附加步骤,这次我从用户 -> 与会者 -> recurring_event -> 事件
  • 追踪