Запрос определенной записи отношения has_many - PullRequest
0 голосов
/ 18 мая 2019

Я сталкивался с этой проблемой несколько раз, но у меня все еще нет элегантного решения.Я хочу найти всех пользователей по значению конкретной ассоциации - «самая последняя» или «любимая» ... что-то, что сужает ассоциацию до 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 голосов
/ 19 мая 2019

У меня нет под рукой моей среды Rails, чтобы попробовать это, но я верю, что вы можете сделать что-то вроде следующего:

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

С точки зрения не-областей, мы делаем следующее:

User.joins(:groups).where(groups: {state: state})
0 голосов
/ 18 мая 2019

Мне не очень понятен ваш вопрос, но он звучит как нечто, что может быть решено с помощью базы данных Graph.SQL Server 2017 поставляется с базой данных Graph.Это не лучший инструмент Graph DB, но, по крайней мере, он бесплатный.

...