开发者

Rails - Why does LINK_To Generate an unnecessary hit to the database?

I have the following code:

<% @photos = Photo.wh开发者_高级运维ere(:photo_album_id => storyitem.feeded_id).limit(4) %>

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

In my logs, I see:

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

After debugging, it's the link_to that is generating that extra database hit even though the first hit for 4 records finds the first query i need for the link_to.

Is there a way to prevent this query from hitting the db 2 times. I want just the query that gets a limit 4, which should give the app all the info it needs.

Thoughts?

UPDATE:

I'd also like to be able to output the following:

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

but that too hits the database again. Any way to hit the database only once for all of the above? thxs


I believe the first hit occurs in code before what you are showing.

Are you sure the line

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

hits the database? Because of lazy loading I think it's only when the second line is run that the database is hit.

I think you need to do more debugging to see where the first database hit occurs.

As for your update, change the first line to

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

to load the photo albums in the same query.


In your case,

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

returns a ActiveRecord::Relation object and it will not hit the DB until you call an enumerable method on it. Or alternatively you call first, all or last on it. Which is done in your second line,

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

Where else in the code are you using @photos?

If you want to absolutely avoid a second call, just call the all method on @photos. Like this:

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

Then for all subsequent uses, it will not hit the DB again. If you further want to avoid a DB hit for photo_album, then you can use include:

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

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜