Как сгенерировать AR-запрос, который возвращает запись A, исключая любые, которые прикреплены к записи B определенного типа - PullRequest
0 голосов
/ 27 февраля 2020

Моими соответствующими таблицами БД являются таблица Счета-фактуры и Таблица авансовых платежей с отношением has_many (в счете-фактуре много авансов). Я пытаюсь сгенерировать запрос ActiveRecord, который будет возвращать все счета за исключением тех, которые прикреплены к любым авансам advance_type:: pre_settlement.

Мой текущий запрос:

  @invoices = invoices.left_joins(:advances).
      where.not('advances.advance_type': :pre_settlement).
      distinct.
      order(period_ends_at: :desc, created_at: :desc) 

Это приводит к следующему SQL:

SELECT "invoices".* FROM "invoices" LEFT OUTER JOIN "advances" ON "advances"."invoice_id" = "invoices"."id" WHERE "advances"."advance_type" != $1  [["advance_type", "pre_settlement"]]

Проблема заключается в том, что в ситуациях, когда счет-фактура имеет несколько авансов, как Если хотя бы один аванс составляет advance_type != :pre_settlement, этот счет будет включен. Я хочу убедиться, что любые счета, которые прикреплены хотя бы к одному предварительному расчету, будут исключены.

1 Ответ

1 голос
/ 27 февраля 2020

Общее решение этой проблемы будет выглядеть примерно так:

class Post < ApplicationRecord
  has_many :comments
  scope :has_flagged_comments, -> { joins(:comments).merge(Comment.flagged) }
end

class Comment < ApplicationRecord
  belongs_to :post
  scope :flagged, -> { where(status: "flagged") }
end

# Posts that don't attract bad behavior:
Post.where.not(id: Post.has_flagged_comments)

У меня может быть отключен какой-то синтаксис, поскольку у меня нет тестового набора данных для его запуска, но это общее подходить. Это сгенерирует запрос примерно так:

select … from posts
where id not in (
 select id from posts
 left join comments on comments.post_id = posts.id
 where status = "flagged"
)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...