Как я могу использовать область в запросе соединения? - PullRequest
0 голосов
/ 23 апреля 2019

Я хочу использовать область объединяемой таблицы. Цель состоит в том, чтобы написать область действия для авторов, имеющих отчеты с определенным значением stat_id (например, 15)

Рельсы 5.2.3

class Author < ApplicationRecord
  belongs_to :report

class Report < ApplicationRecord
  has_many :authors
  scope :with_stat, ->(s) {
    where(stat_id: s)
  }

Это прекрасно работает:

Autor.joins(:report).where(reports: {stat_id: 15})

Если сфера более сложная. Как я могу использовать область из класса Report? Это не работает:

Autor.joins(:report).where(reports: {with_stat(15)})

Какой правильный синтаксис?

1 Ответ

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

Эта область не даст вам правильный запрос.

То, что вы хотите, это Author.joins(:report).where(reports: { stat_id: 1 }). Который дает один запрос:

Author Load (1.0ms)  SELECT  "authors".* FROM "authors" INNER JOIN "reports" ON "reports"."id" = "authors"."report_id" WHERE "reports"."stat_id" = $1 LIMIT $2 

Вот что происходит, если вместо этого вы используете область действия:

irb(main):004:0> Author.joins(:report).where(Report.with_stat(1))
  Report Load (1.6ms)  SELECT "reports".* FROM "reports" WHERE "reports"."stat_id" = $1  [["stat_id", 1]]
  Author Load (0.6ms)  SELECT  "authors".* FROM "authors" INNER JOIN "reports" ON "reports"."id" = "authors"."report_id" LIMIT $1  [["LIMIT", 11]]
=> #<ActiveRecord::Relation []>
irb(main):005:0> Author.joins(:report).where(report: Report.with_stat(1))
  Author Load (2.1ms)  SELECT  "authors".* FROM "authors" INNER JOIN "reports" ON "reports"."id" = "authors"."report_id" WHERE "authors"."report_id" IN (SELECT "reports"."id" FROM "reports" WHERE "reports"."stat_id" = $1) LIMIT $2  [["stat_id", 1], ["LIMIT", 11]]
=> #<ActiveRecord::Relation []>

Последний использует подзапрос, который должен дать тот же результат, но должен быть менее эффективным.

То, что вы можете сделать, это поместить прицел на другую сторону ассоциации:

class Author < ApplicationRecord
  belongs_to :report

  scope :with_stat, ->(s){
    joins(:report).where(reports: {stat_id: s})
  }
end

irb(main):010:0> Author.joins(:report).where(reports: { stat_id: 1 })
  Author Load (1.1ms)  SELECT  "authors".* FROM "authors" INNER JOIN "reports" ON "reports"."id" = "authors"."report_id" WHERE "reports"."stat_id" = $1 LIMIT $2  [["stat_id", 1], ["LIMIT", 11]]
=> #<ActiveRecord::Relation []>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...