Cookies setting
0

Next and previous buttons

This is a quick tutorial on how to add next and previous buttons to an image. I’ll explain two ways to do the same thing and add some useful tips that could make your life easier. I usually use will_pagiante for all my pagination needs and what I am doing here can also be achieved with it, but that may seem just too much work for a simple problem. When I was looking for a solution I didn’t find much useful information, so I’ve decided to change that.
In my gallery application (I’ll write more details on that in one of my next blog posts), I have many galleries that have many images. For a more simple solution, just remove the gallery parts. As I upload multiple images at once, sorting by created_at will never work. The solution is to first install a gem called
acts-ac-list. With this you add a position column to your images table and you can now always have your items in the correct order and easy to define, which are the first and last in the list. You can also use this for all sorting functionality in your application. Ryan Bates talks about it in this screencast.

Solution 1:

You add this to your Image model :

 def next
   self.class.find :first,
        :conditions =>  ["position > ? AND gallery_id = ?", position, gallery_id],
        :order => " position DESC"

  end

  def previous
     self.class.find :first,
          :conditions => ["position < ? AND gallery_id = ?", position, gallery_id],
          :order => " position DESC"
  End

In your view you do this (I use haml):

= link_to “Next”, gallery_image_path(@gallery, @image.next)

Solution 2:

Add this two named_scope-s to your Image model

named_scope :next, lambda { |p| {:conditions => ["position < ? AND gallery_id = ?", p.position , p.gallery_id], :limit => 1, :order => "position  DESC"} }

 

named_scope :previous, lambda { |p| {:conditions => ["position  > ? AND gallery_id = ?", p.position , p.gallery_id], :limit => 1, :order => "position  ASC"} }

In your Images controller you have to add @previous_image and @next_image:

 

@previous_image = Image.previous(@image)
@next_image = Image.next(@image)

In your view:

= link_to 'previous', gallery_image_path(@gallery, @previous_image)

To check the first and last item and consequently not get errors I’ve also added
these bits of code:

In the images controller:

 @all_images = @gallery.images.all

In the view:

- if @image.position != @all_images.size  for the last item
- if @image.position != 1 for the first item in the list.

I hope this can be helpful to someone, if you want to add or ask anything leave a comment below.

02 May 2010 at 20:39
RoR




(required)

(required)