Я использую Rails 5.2.2 и хочу улучшить свои запросы к БД, чтобы не перегружать базу данных ненужными запросами, что происходит в данный момент, кроме того, код должен быть понятен. Я сам пытался выяснить, как реализовать объект запроса (с небольшой помощью этой статьи и , что тоже ) без каких-либо положительных результатов.
Я хочу улучшить эти методы, любые предложения приветствуются:
def last_month
Shareholder.
non_free_account(beginning_of_this_month).
where("created_at >= ? AND created_at <= ?", beginning_of_last_month, beginning_of_this_month)
end
def never_sub?(shareholder)
ShareholderSubscription.where(shareholder_id: shareholder.id).empty? && shareholder.previously_subscribed == false
end
def owner_has_one_shareholder?(shareholder)
ShareholdersUser.where(user_id: shareholder.owner_id).
where.not(shareholder_id: shareholder.id).exists?
end
Я думаю, что если я буду использовать более сложный SQL-запрос с условиями joins
, where
и т. Д., В результате код будет более эффективным и понятным. Возможно, мне не понадобится и этот сложный метод вызова.
def call
prop_shareholders
end
private
def prop_shareholders
shareholders_last_month = last_month
shareholders_last_month.each_with_object([]) do |shareholder, apt|
if never_sub?(shareholder) && owner_has_one_shareholder?(shareholder)
apt << shareholder
end
end
end
UPDATE:
Хорошо, поэтому через несколько дней я сделал этот запрос:
Shareholder.
non_free_account(beginning_of_this_month).
where("shareholders.created_at >= ?", beginning_of_last_month).
where("shareholders.created_at <= ?", beginning_of_this_month).
joins("LEFT JOIN shareholder_subscriptions ON shareholder_subscriptions.shareholder_id = shareholders.id").
where(shareholder_subscriptions: { id: nil }).
joins("RIGHT JOIN shareholders_users ON shareholders_users.shareholder_id = shareholders.id").
where("shareholders_users.user_id IN (SELECT user_id FROM shareholders_users
GROUP BY shareholders_users.user_id
HAVING COUNT(shareholders_users.user_id) = 1)")
И это решение этой задачи. Однако я думаю, что было бы еще сложнее, если бы вы применили ActiveRecords для всех запросов - я имею в виду и подзапрос, но я не знаю, как это сделать. Может быть, кто-нибудь может дать мне несколько советов по этому поводу?