查询has_many关系的特定记录

时间:2019-05-18 01:24:17

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

我已经遇到过几次这个问题,但是我仍然没有一个好的解决方案。我想通过特定关联的值-“最近”或“收藏夹”来查找所有用户...将关联范围缩小到1左右的东西。

class User
  has_many :group_memberships
  has_many :groups, through: :group_memberships do
    def favorite
      rank(:priority).first
    end
  end
end

class GroupMembership
  belongs_to :group
  belongs_to :user
end

class Group
  has_many :group_memberships
  has_many :users, through: :group_memberships

  scope :in_state, ->(state) { where(state: state) }
end

因此,在这种情况下,假设用户可以对他们所在的组进行排名。我想通过查询他们喜欢的组来查找所有用户。他们已经设置了所有所属组的优先级,我们在这里不必担心。

例如,我想查找所有喜欢的组处于特定状态的用户。这是我最近的尝试,但不起作用...

class User
  ...
  scope :favorite_group_in, lambda { |state|
    subquery = Group.rank(:priority).select(:id).limit(1).to_sql
    distinct.left_outer_joins(:groups)
            .where("groups.id = (#{subquery})")
            .merge(Group.in_state(state))
  }
end

我尝试创建一个has_one,并尝试通过它进行查询,但这会查询整个表,而不是将其范围限定为has_one。我已经在postgres中尝试了窗口函数。我在原始SQL中尝试过子查询。我不能是唯一一个有这个问题的人。查询关联子集的常规解决方案是什么?

起作用的是这个...但是出于性能原因,我正在寻找纯SQL实现。

class User
  ...
  scope :favorite_group_in, lambda { |state|
    ids = distinct.left_outer_joins(:groups).select { |u| u.groups.primary&.in_state?(state) }.pluck(:id)
    where(id: ids)
  }
end

2 个答案:

答案 0 :(得分:-1)

我没有我的Rails环境可以尝试此操作,但我相信您可以执行以下操作:

class User < ApplicationRecord
    ...
    scope :favorite_group_in, ->(state) { joins(:groups).where(groups: {state: state}) }
    ...

就非范围而言,我们正在执行以下操作:

User.joins(:groups).where(groups: {state: state})

答案 1 :(得分:-2)

对于您的问题,我不太清楚,但这听起来像是Graph数据库可以解决的问题。 SQL Server 2017随附Graph数据库。它不是最好的Graph数据库工具,但至少它是免费的。