Rails эффективный способ найти пользователя только с одним акционером - PullRequest
0 голосов
/ 25 апреля 2019

В моем методе я хочу проверить, есть ли у пользователя только один акционер, и должен ли он возвращать true (позже он используется в блоке if).По сути, он должен отражать что-то вроде User.find_by(id: user.id).shareholder.count < 1, потому что он перегружает базу данных ненужными запросами (у меня есть база данных с ~ 30k пользователей).

Я думал о том, чтобы создавать запросы с where, поэтому у меня есть этот:

def one_shareholder?(shareholder)
  ShareholdersUser.where(user_id: shareholder.owner_id).
                   where.not(shareholder_id: shareholder.id).exists?
end

Но я не знаю, как реализовать запрос, который будет учитываться, если у этого пользователя только один акционер.Должен ли я использовать что-то вроде find_each?

Редактировать:

user has_many :shareholder

shareholder belongs_to :owner

ShareholdersUser belongs_to :user and :shareholder

Ответы [ 2 ]

1 голос
/ 25 апреля 2019

Может быть, это может дать вам подсказку.Я использовал нечто подобное в проекте, где у меня есть эти модели:

class Company < ApplicationRecord
  has_many :permits
end

и

class Permit < ApplicationRecord
  belongs_to :company
end

Для получения компаний, имеющих только одно разрешение, я использовал:

Company.joins(:permits).group('companies.id').having('count(company_id) = 1')


Может быть, вы можете взять идентификаторы и использовать массив, чтобы проверить, находится ли компания в массиве.Например:
ids_of_companies_having_one_permit = Company.joins(:permits).group('companies.id').having('count(company_id) = 1').pluck(:id)

Затем проверьте:

if ids_of_companies_having_one_permit.include? company.id ....


Это поток, за которым я следовал: Найти все записи, в которых количество ассоциаций больше нуля
0 голосов
/ 25 апреля 2019

Во-первых, если вы находите пользователя по его ID, то можете напрямую использовать User.find(user.id) вместо User.find_by(id: user.id)

Во-вторых, как вы упомянули в своем вопросе, вы хотите либо true, либо false для вашего условия if.

И в соответствии с вашим запросом, я думаю, что вы установили user has_many shareholder связь.

Таким образом, вы можете напрямую использовать User.find(user.id).shareholders < 1 в своем условии if, как показано ниже,

if User.find(user.id).shareholders.count < 1
     #do something...
end

Примечание: я использовал множественное число акционеров по условию, потому что у нас есть ассоциация has_many

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...