Rails: Get next / previous record

My app has Photos that belong to Users.

In a photo#show view I'd like to show "More from this user", and show a next and previous photo from that user. I would be fine with these being the next/previous photo in id order or the next/previous photo in created_at order.

How would you write that kind of query for one next / previous photo, or for multiple next / previous photos?


Try this:

class User
  has_many :photos
end


class Photo
  belongs_to :user

  def next
    user.photos.where("id > ?", id).first
  end

  def prev
    user.photos.where("id < ?", id).last
  end

end

Now you can:

photo.next
photo.prev

It lead me to a solution for my problem as well. I was trying to make a next/prev for an item, no associations involved. ended up doing something like this in my model:

  def next
    Item.where("id > ?", id).order("id ASC").first || Item.first
  end

  def previous
    Item.where("id < ?", id).order("id DESC").first || Item.last
  end

This way it loops around, from last item it goes to the first one and the other way around. I just call @item.next in my views afterwards.


Not sure if this is a change in Rails 3.2+, but instead of:

model.where("id < ?", id).first

for the previous. You have to do

.where("id > ?", id).last

It seems that the "order by" is wrong, so first give you the first record in the DB, because if you have 3 items lower than the current, [1,3,4], then the "first" is 1, but that last is the one you ware looking for. You could also apply a sort to after the where, but thats an extra step.


class Photo < ActiveRecord::Base
  belongs_to :user
  scope :next, lambda {|id| where("id > ?",id).order("id ASC") } # this is the default ordering for AR
  scope :previous, lambda {|id| where("id < ?",id).order("id DESC") }

  def next
    user.photos.next(self.id).first
  end

  def previous
    user.photos.previous(self.id).first
  end
end

Then you can:

photo.previous
photo.next