【问题标题】:ActiveRecord query where all associations included包含所有关联的 ActiveRecord 查询
【发布时间】:2017-04-09 15:45:52
【问题描述】:

例如,假设我有这三个表: 事件、出勤(加入表)和用户。

Event has_many attendances and has_many users through attendances
User has_many attendances and has_many events through attendances
Attendance belongs_to attendance and belongs_to user

我希望能够查询所有活动以找到 x 用户都参加的地方。 举个例子:

Event     | Users who attended Event
1               [1, 3, 4, 6, 9]
2               [1, 4, 9]
3               [3, 4, 6]
4               [2, 3, 6]

我想说 Event.by_attendended_users(user_4, user_9) 并得到 Events: [1, 2]

我在想一些类似于joins(:attendances).where("attendances.user_id IN :user_ids") 或类似的东西,但还没有完全按预期工作。非常感谢任何帮助或反馈!

编辑:作为一些额外的细节,正如@AbM 指出的那样, 如果加入一次只针对 2 个用户,则可以使用一些技巧来查找用户。 该解决方案不起作用,因为查询的第二部分覆盖了第一部分。

理想情况下,这应该能够在任意数量的关联上工作,尽管最低要求只是说它需要使用 2。(目前)

此外,我希望能够将其用作范围,这意味着它可以链接到其他范围以进一步过滤。仅当在其他过滤器链中首先调用该范围时,@AbM 的解决方案才适用于此。

【问题讨论】:

  • @AbM - 非常聪明!理想情况下,我想考虑使用超过 2 个用户的情况,但这是目前的最低要求,所以如果没有更好的解决方案,我会很乐意使用这个。 :) 谢谢!
  • 这似乎不起作用。我认为where(attendances: {user_id: user_9.id}) 覆盖了初始范围并返回到原始问题。 :(

标签: ruby-on-rails postgresql activerecord


【解决方案1】:
user_ids = [4, 9]
events = Event
user_ids {|user_id| events = events.where(id: Event.joins(:attendances).where(attendances: {user_id: user_id})) }
events

另一种方法是使用自定义计数:

user_ids = [4, 9]
Event.joins(:attendances).having('COUNT(CASE WHEN attendances.user_id IN (?) THEN 1 END) = ?', user_ids, user_ids.length).group(:id)

【讨论】:

  • 这不允许一个用户多次参加同一活动,因为搜索结果会因计数而变得混乱。但这是一个好的开始。我可以使用常规的数组操作手动完成其余的工作。
  • 我不太清楚你的意思。为什么一个用户会多次参加同一个活动?
【解决方案2】:
user_ids = [1, 3, 5]
events = Event.joins(:attendances)
user_ids.each {|user_id| events = events.where('attendances.user_id = ?', user_id) }

# events now contains all events where all specified users attended

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-05-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-15
    • 2023-03-11
    • 1970-01-01
    相关资源
    最近更新 更多