Rails Inner Join не работает, но SQL выглядит правильно - PullRequest
1 голос
/ 04 апреля 2011

Итак, у меня есть 2 таблицы, которые объединены идентификатором. Я в консоли рельсов и набираю:

Programmer.all(:joins=>:assignment)

генерируется sql:

SELECT `programmers`.* FROM `programmers` INNER JOIN `assignments` ON `assignments`.`programmer_id` = `programmers`.`id`

Выходные данные такие же, как и у Programmer.all. Почему он не включает данные о назначениях?

Ответы [ 2 ]

5 голосов
/ 04 апреля 2011

Полагаю, я в основном переоценил ваш вопрос. Если вы просто хотите присоединиться к любым доступным заданиям для программистов, вы ищете:

Programmer.all(:include => :assignment)

Rails спроектирован таким образом, что :joins используется для выполнения таких операций, как сортировка и захват определенных записей, но при этом сохраняет результат запроса до минимального размера - это означает, что :joins фактически никогда не включает результаты из объединенной таблицы в результат.

Теперь вот мой предыдущий ответ, который предполагает, что вы хотите выполнить INNER JOIN, чтобы получить только программистов с заданиями, но вы также хотите эти данные. В этом случае у вас есть два варианта:

# 1 - Использование :select

Programmer.all(:select => '*', :joins => :assignment)

Это изменит SQL на:

SELECT * FROM `programmers` INNER JOIN `assignments` ON `assignments`.`programmer_id` = `programmers`.`id`

Перевернутая сторона: вы получаете запрос, который вам нужен, и все данные находятся где-то, по крайней мере.

Недостаток: assignments присваивается непосредственно объекту Programmer, а не соответствующему месту в Programmer.assignment.

# 2 - используйте комбинацию :joins и :includes

Programmer.all(:joins => :assignment, :include => :assignment)

, который производит SQL:

SELECT `programmers`.* FROM `programmers` INNER JOIN `assignments` ON `assignments`.`id` = `programmers`.`assignment_id`
SELECT `assignments`.* FROM `assignments` WHERE (`assignments`.`id` IN  (?) )

Upside: все ваши данные сейчас находятся в нужном месте. Вы можете ссылаться на programmer.assignment без другого запроса.

Недостаток: вы выполняете этот дополнительный запрос во многих случаях. Я вполне уверен, что Rails пытается оптимизировать это, когда это необходимо, и если нет, это не должно вызывать у вас слишком много накладных расходов.

0 голосов
/ 24 октября 2017

Просто вы можете сделать как

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