【问题标题】:Query on model associated as belongs_to in ActiveRecord (Is there a better way)在 ActiveRecord 中查询作为 belongs_to 关联的模型(有没有更好的方法)
【发布时间】:2020-03-30 07:36:48
【问题描述】:

我有两个模型

class InterestingGuest < ApplicationRecord
  # column_name
  # recommended_to
  # recommendee

  belongs_to :recommended_to, class_name: 'User'
  belongs_to :recommendee, class_name: 'User'
end
class User < ApplicationRecord
  # column_name
  # membership_level : ['Member', 'Guest']

  has_many :guest_recommendations, class_name: 'InterestingGuest',
                                   foreign_key: 'recommended_to_id',
                                   dependent: :destroy

  has_many :recommendees, class_name: 'InterestingGuest',
                          foreign_key: 'recommendee_id',
                          dependent: :destroy
end

我正在尝试查找所有recommendees,其中membership_levelGuest

我尝试的查询是

recommendees = InterestingGuest.where(recommended_to_id: user_id))
                               .pluck(:recommendee_id)
guests = User.where(id: recommendees).where(membership_level: 'Guest')

尽管它可以达到目的,但有没有更好的方法在单个查询中实现相同目的

【问题讨论】:

  • 你可以试试这个查询,我根据你的帖子创建了这个查询。 InterestingGuest.join("LEFT OUTER JOIN users on users.user_id = interesting_guests.recommendee_id where users.membership_level = 'Guest'")
  • 嘿@RohitLingayat 感谢您的回复,但这最终会在每个user 上运行查询,而我试图找到所有recommendeesmembership_level 是客人并且是@987654331 @特定用户。
  • 它不会为每个用户执行查询,它只会对匹配的用户执行。 users.user_id = interesting_guests.recommendee_id 上有左连接,同样你也可以在 where 子句中添加 recommended_to
  • 啊,知道了,谢谢。此查询有效:InterestingGuest.joins("LEFT OUTER JOIN users on users.id = interesting_guests.recommendee_id where users.membership_level = 'Guest' and recommended_to_id = 1")
  • (y) 我将此评论作为答案。如果此查询解决了您的问题,您可以投票

标签: sql ruby-on-rails ruby activerecord


【解决方案1】:

您可以在这种情况下使用LEFT OUTER JOIN

试试:

InterestingGuest.join("LEFT OUTER JOIN users on users.user_id = interesting_guests.recommendee_id where users.membership_level = 'Guest'")

这里user_id 表示recommendee_id,根据你在课堂上提到的关联。

【讨论】:

    【解决方案2】:

    Rails: ActiveRecord query based on association value 应该可以帮到你。

    试试:

    InterestingGuest.joins(:users).where(users:{ membership_level: 'Guest' })
    

    InterestingGuest.joins(:users).where('users.membership_level' = 'Guest')
    

    我个人认为第一个看起来更整洁。

    官方文档: https://guides.rubyonrails.org/active_record_querying.html#joining-tables

    【讨论】:

    • 感谢您的回复,但在InterestingGuest 上加入users 将不起作用,因为关联是通过recommended_torecommendee 进行的
    • 另外,我在这里尝试的查询是获取recommendees,其membership_levelguest 并且是recommended_to 特定用户
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-21
    • 1970-01-01
    相关资源
    最近更新 更多