Как выбрать записи с нулевыми ассоциациями из двух has_many? - PullRequest
1 голос
/ 12 октября 2019

У меня есть следующие модели:

class Report < ApplicationRecord
  belongs_to :departure, class_name: 'Stop'
  belongs_to :arrival, class_name: 'Stop'
end
class Stop < ApplicationRecord
  has_many :departure_reports, foreign_key: 'departure_id', class_name: 'Report'
  has_many :arrival_reports, foreign_key: 'arrival_id', class_name: 'Report'
end

Это соответствующие миграции:

class CreateReports < ActiveRecord::Migration[5.2]
  def change
    create_table :reports do |t|
      t.references :departure, foreign_key: { to_table: :stops }
      t.references :arrival, foreign_key: { to_table: :stops }

      t.timestamps
    end
  end
end
class CreateStops < ActiveRecord::Migration[5.2]
  def change
    create_table :stops do |t|
      t.timestamps
    end
  end
end

Как выбрать stops, которые не имеютлюбой связанный report как departure или arrival?

Ответы [ 2 ]

2 голосов
/ 12 октября 2019

Вы можете попытаться использовать joins для определения своего left outer join, проверив строки в таблице stops, которые по их идентификатору совпадают с departure_id и / или arrival_id в таблице reports.

После этого предложение where можно использовать для фильтрации тех отчетов, где departure_id или arrival_id равны NULL:

Stop
  .joins('left outer join reports on stops.id IN (reports.departure_id, reports.arrival_id)')
  .where('reports.departure_id IS NULL OR reports.arrival_id IS NULL')
0 голосов
/ 15 октября 2019

Вы можете

class Stop
  scope :without_reports, -> {
    where(_not_exists(Report.where("stops.id IN (departure_id, arrival_id)")))
  }

  def self._not_exists(scope)
    "NOT EXISTS(#{scope.to_sql})"
  end
end

заменить NOT EXISTS на EXISTS, чтобы получить остановки с отчетами

> Stop.without_reports
SELECT "stops".* FROM "stops" WHERE (NOT EXISTS(SELECT "reports".* FROM "reports" WHERE (stops.id IN (departure_id, arrival_id))))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...