views:

48

answers:

5

I have an ActiveRecord model object @gallery which represents a row in the Galleries MYSQL table. Is there a way for me to ask @gallery to give me the id to the next gallery object in the table?

The obvious way for me to do this is to :

@galleries = Gallery.find(:all)
index = @galleries.index(@gallery)

@nextgallery = @galleries[index+1]

but then I have to nilsafe this and I'm unnecessarily making another DB call to fetch all records. Any other way out?

+2  A: 

Are you really sure that you're making a second db call? If so, does it really matter? Is this deep in a 4x nested loop where every call matters?

If not, pre-optimizing may be your downfall. AR:B does a lot of caching and iirc find(:all) returns an array or Hash so index+1 should be okay.

Chuck Vose
A: 

The code you presented is a good thing to do. The find(:all) method fetches by default all records of the galleries table, in the following way (you can see it when running WEBrick in development mode)

SELECT * FROM galleries

The results of this query are cached and reused every time you access @galaeries, this is also visible (when running WEBrick) since no other database calls are made.

Veger
A: 

I don't believe there is a way to get the next gallery from your @gallery instance without hitting the database.

You could however only hit the database once if you did something like

@galleries = Gallery.find(:all)
@gallery = @galleries.detect{|g| g.id == params[:gallery_id]}
index = @galleries.index(@gallery)
@nextgallery = @galleries[index+1]

Hence you only hit the database once. This is only bad if you have a large number of galleries, in which case it would make sense to write a next method to your gallery which does hit the database

DanSingerman
+1  A: 

First of all you should define some criteria to decide order of your galleries. In MySQL when you will do

 SELECT * FROM galeries

it can give you different order of returned records. So on example if you order them by creation time then you can do something like this:

 @nextgallery = Gallery.find(
                   :first, 
                   :order => "created_at ASC", 
                   :conditions => "created_at > #{@gallery.created_at}"
                 )

In this example you should be careful with @gallery.created_at because Rails stores in database time in GMT +0 time format, but in @gallery.created_at it is with your local configuration (on example +2 h). To change it use: @gallery.created_at.gmtime.to_s

klew
A: 

Are you by any chance trying to will_paginate the galleries?

Tim Snowhite