【问题标题】:Problems crafting a multi level nested ActiveRecord query制作多级嵌套 ActiveRecord 查询的问题
【发布时间】:2019-01-13 07:42:09
【问题描述】:

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

日历事件由一个或多个 RecurringEvents 组成。一个 RecurringEvent 有一个或多个参加者。与会者表基本上是一个联接表,列出了参加 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 $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

【问题讨论】:

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


    【解决方案1】:

    回答 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:这将为特定事件提供 users 表

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

    【讨论】:

    • 快到了! RecurringEvent.joins(:event, :attendees).where('event_id = 453 AND attendees.status = ?', 2) 返回一个带有 RecurringEvents 的数组。 status 必须是 int,因为 Attendee.status 是一个枚举。我们如何设计查询以返回参与的用户?
    • 我看到我的类命名可能有点混乱。我需要查询返回的是参加活动的用户列表。 :)
    • 看我的回答3
    • 非常感谢很多的帮助! :-)
    • 老实说,我对你的问题感到很开心,对每个答案都充满挑战和升级 :-)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-09
    • 2023-04-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-05
    相关资源
    最近更新 更多