Rails - Почему LINK_To генерирует ненужное попадание в базу данных? - PullRequest
2 голосов
/ 15 декабря 2010

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

<% @photos = Photo.where(:photo_album_id => storyitem.feeded_id).limit(4) %>

<%= link_to 'Image Set', project_photo_album_path(storyitem.project, @photos.first.photo_album_id) %>

В своих логах я вижу:

Photo Load (0.4ms)  SELECT "photos".* FROM "photos" WHERE ("photos"."photo_album_id" = 72) ORDER BY photos.created_at DESC, photos.version DESC LIMIT 1
Photo Load (0.7ms)  SELECT "photos".* FROM "photos" WHERE ("photos"."photo_album_id" = 72) ORDER BY photos.created_at DESC, photos.version DESC LIMIT 4

После отладки именно link_to генерирует дополнительное попадание в базу данных, хотя первое попадание для 4 записей находит первый запрос, который мне нужен для link_to.

Есть ли способ предотвратить попадание этого запроса в базу данных 2 раза. Мне нужен только запрос, который получает ограничение 4, которое должно дать приложению всю необходимую информацию.

Мысли

UPDATE:

Я также хотел бы иметь возможность вывести следующее:

<%=  @photos.first.photo_album.title %>

но это снова попадает в базу данных. Любой способ попасть в базу данных только один раз для всего вышеперечисленного? thxs

Ответы [ 2 ]

1 голос
/ 15 декабря 2010

В вашем случае

<% @photos = Photo.where(:photo_album_id => storyitem.feeded_id).limit(4) %>

возвращает объект ActiveRecord::Relation, и он не попадет в БД, пока вы не вызовете для него метод enumerable.Или же вы звоните first, all или last.Что делается во второй строке,

<%= link_to 'Image Set', project_photo_album_path(storyitem.project, @photos.first.photo_album_id) %>

Где еще в коде вы используете @photos?

Если вы хотите полностью избежать второго вызова, просто позвоните на all метод @photos.Например:

<% @photos = Photo.where(:photo_album_id => storyitem.feeded_id).limit(4).all %>

Тогда для всех последующих применений он не будет снова попадать в БД.Если вы хотите избежать попадания в БД для photo_album, вы можете использовать include:

<% @photos = Photo.where(:photo_album_id => storyitem.feeded_id).limit(4).include(:photo_albums).all %>
1 голос
/ 15 декабря 2010

Я считаю, что первое попадание происходит в коде перед тем, что вы показываете.

Вы уверены, что строка

<% @photos = Photo.where(:photo_album_id => storyitem.feeded_id).limit(4) %>

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

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

<% @photos = Photo.where(:photo_album_id => storyitem.feeded_id).limit(4).includes(:photo_albums) %>

, чтобы загрузить фотоальбомы в том же запросе.

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