Проблемы при создании многоуровневого вложенного запроса ActiveRecord - PullRequest
0 голосов
/ 13 января 2019

Я создаю приложение календаря в Rails. Можно приглашать людей на мероприятия. У меня проблемы с написанием запроса типа @event.attending_users.

Событие календаря состоит из одного или нескольких повторяющихся событий. У одного повторяющегося события есть один или несколько участников. Таблицы участников - это, по сути, таблица соединений, в которой указывается, какие пользователи посещают 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

приложение / модели / 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 голосов
/ 13 января 2019

Ответ 1 (как вопрос выше),

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

пояснения

  • Вы можете присоединиться одной командой
  • , так как статус - это столбец у посетителей, я включаю имя таблицы перед полем статуса

коррекция 2:

эта команда ниже вернет записи участников

Attendee.joins(recurring_event: :event).where('events.event_id = ? AND attendees.status = ?',453,2)
  • мое предложение не использовать непосредственно номер внутри, где заявление, я дал образец выше
  • модели соединения теперь изменены с вышеупомянутым, так как участник получает доступ к 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 -> событие
...