Стремитесь загрузить связанную запись, также присоединяясь к ней в Rails - PullRequest
0 голосов
/ 22 декабря 2010

Допустим, у меня есть книги, каждая из которых принадлежит автору. Я хотел бы распечатать список книг, а также некоторую информацию об авторе. В качестве начального прохода я бы просто использовал

@books = Book.all

В моем контроллере и

book.author.name

На мой взгляд, в результате @books.count отдельных запросов (проблема "n + 1"). Рекомендуемое решение:

@books = Books.includes(:author)

Что сводит его к постоянному количеству запросов.

Теперь, если бы мне нужно было отфильтровать список книг по некоторым критериям, связанным с автором, я бы сделал это в контроллере

@books = Books.joins(:author).where('name like "%Richler%"')

Но это вновь вызывает проблему "n + 1". Если я пытаюсь вписать в запрос .includes(:author), он попытается втянуть его дважды, и name станет неоднозначным. В обычном MySQL я бы просто использовал что-то вроде:

SELECT * FROM books LEFT OUTER JOIN authors ON books.author_id = authors.id
  WHERE authors.name LIKE "%Richler%";

или

SELECT * FROM books, authors WHERE
  authors.name LIKE "%Richler%" AND books.author_id = authors.id;

Но если не написать только строку SQL-запроса, как Railsish может это сделать?

1 Ответ

4 голосов
/ 22 декабря 2010

Это должно сделать работу:

Book.joins(:author).where('authors.name like "%Richler%"').includes(:author)

Это должно запустить только два SQL-запроса.

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