Ruby on Rails с объектом запроса, чтобы сделать чистый код и быстрее БД - PullRequest
0 голосов
/ 24 апреля 2019

Я использую 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 для всех запросов - я имею в виду и подзапрос, но я не знаю, как это сделать. Может быть, кто-нибудь может дать мне несколько советов по этому поводу?

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