制作多层嵌套ActiveRecord查询时出现问题

时间:2019-01-13 07:42:09

标签: ruby-on-rails activerecord rails-activerecord

我正在Rails中构建日历应用程序。 可以邀请人们参加活动。 我在编写类似@event.attending_users的查询时遇到困难。

日历事件包含一个或多个RecurringEvent。一个RecurringEvent具有一个或多个参与者。与会者表基本上是一个联接表,其中列出了正在参加RecurringEvent的用户。

事件

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

RecurringEvent

 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 $1

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" = $1 AND "recurring_events"."status" = $2 ORDER BY "recurring_events"."id" ASC LIMIT $3

1 个答案:

答案 0 :(得分:0)

答案1(如上所述)

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

说明

  • 您可以使用一个命令加入
  • 由于状态是与会者中的一列,因此我在状态字段之前包括表格名称

更正2:

下面的此命令将返回与会者记录

Attendee.joins(recurring_event: :event).where('events.event_id = ? AND attendees.status = ?',453,2)
  • 我的建议不要在where语句中直接使用数字,我在上面给出了示例
  • 自从与会者访问recurring_event和recurring_event访问事件以来,联接模型现在随着上述变化(请参见上面与我的回答的区别。这意味着根据recurring_event访问事件)

答案3:这将为用户提供特定事件的表

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->事件中跟踪的