Rails с использованием ‘where’ в модели, имеющей отношение has_many

#ruby-on-rails #ruby #activerecord #activemodel

#ruby-on-rails #ruby #activerecord #activemodel

Вопрос:

У меня есть 2 модели, Account и User

 class Account
  has_many :users
end

class User
  belongs_to :account
end
  

Соответствующие детали модели для моей проблемы:

  • Каждая учетная запись имеет subscription тип, который может быть либо standard , premium либо enterprise

Как мне правильно перечислить все Users , что принадлежит premium учетной записи? Кроме того, как мне перечислить всех пользователей во всех premium учетных записях, поскольку может быть любое количество premium учетных записей.

Я попробовал несколько вариантов приведенных ниже действий:

 Account.where(subscription: "premium").users # undefined method users

User.where(subscription: "premium") # returns nothing

Account.where(subscription: "premium").each do |account|
  account.users # seems to return an array?
end

  

Комментарии:

1. Пожалуйста, воздержитесь от задания нескольких вопросов в одном — вместо этого создайте отдельный вопрос.

Ответ №1:

То, что вам нужно, — это левое внутреннее соединение:

 User.joins(:account)
    .where(accounts: { subscription: "premium" })
  

Это вернет все записи из таблицы users, которые имеют совпадение в объединенной таблице.

Как мне правильно перечислить всех пользователей, принадлежащих премиум-аккаунту?

Если вы имеете в виду пользователей, принадлежащих определенной учетной записи, вы должны вызвать #users метод для этой конкретной учетной записи.

 account = Account.eager_load(:users).find(1)
account.users
  

Ответ №2:

На ваш первый вопрос:

перечислите всех пользователей, принадлежащих премиум-аккаунту:

Ваша первая попытка ( Account.where(subscription: "premium").users ) не работает, потому Account.where(subscription: "premium") что уже возвращает много учетных записей, поэтому список (точнее, объект отношения ActiveRecord), и вы не можете вызвать .users этот список. Вы можете вызывать только .users одну учетную запись, вам нужен join оператор для объединения обеих таблиц. Подробнее об этом можно прочитать здесь: https://guides.rubyonrails.org/active_record_querying.html#joining-tables И поскольку вам нужны пользователи, вы должны начать с user .

Ваш запрос должен выглядеть примерно так:

 User.joins(:account).where(accounts: {subscription: "premium"})
  

Это даст вам всех пользователей, у которых есть учетная запись с типом подписки premium.

Я думаю, что ваш второй вопрос относительно запроса практически тот же

Кроме того, как мне перечислить всех пользователей во всех премиум-аккаунтах, поскольку может быть любое количество премиум-аккаунтов.

Ответ №3:

Другие ответы отличные, другой вариант будет в Account model

 scope :premium, -> { where(subscription: 'premium') }
  

и ваш запрос

 User.joins(:account).merge(Account.premium)