= acts_as_ordered

If you find this plugin useful, please consider a donation to show your support!

  http://www.paypal.com/cgi-bin/webscr?cmd=_send-money
  
  Email address: jonathan.viney@gmail.com
  
== Instructions

This plugin gives ActiveRecord models an easy way to find their neighbours in a given order.

== Resources

Install
  * script/plugin install http://svn.viney.net.nz/things/rails/plugins/acts_as_ordered

== Usage

  class Person < ActiveRecord::Base
    acts_as_ordered :order => 'first_name'
  end

Say you have people with first names of Adam, Jonathan and Robert:

  p = Person.find_by_first_name('Jonathan')
  
  p.next              # Robert
  p.previous          # Adam
  p.previous.previous # Adam   (does not wrap around to end)
  p.next.next         # Robert (does not wrap around to start)
  
If you want the next and previous methods to wrap around the ends, use:

  acts_as_ordered :order => 'first_name', :wrap => true
  
You can also jump by more than one at a time:

  # Without wrapping (clamps to ends)
  p = Person.find_by_first_name('Jonathan')
  p.next(:number => 2)       # Robert
  p.next(:number => 100)     # Robert
  p.previous(:number => 100) # Jonathan
  
  # With wrapping (wraps around ends as many times as you like)
  p = Person.find_by_first_name('Jonathan')
  p.next(:number => 8)       # Adam
  p.previous(:number => 17)  # Robert
  
You can use this to get the next/previous model that matches some condition:

  class Person < ActiveRecord::Base
    acts_as_ordered :condition => proc { |p| p.age > 10 }
    
    # Or check that a method on the model returns true
    acts_as_ordered :conditions => :male?
  end
  
In this case, the next and previous methods will return the closest adjacent object that matches the condition.
  
You can use this in a application to be able to quickly browse through people. Eg:

  class PersonController < ApplicationController
    def view_neighbour
      # params[:direction] is passed off the page as 'next' or 'previous'
      @person = Person.find(params[:id]).find_by_direction(params[:direction])
      render :action => 'view'
    end
    
    # Or alternatively...
    def view_next
      @person = Person.find(params[:id]).next
      render :action => 'view'
    end
    
    def view_previous
      @person = Person.find(params[:id]).previous
      render :action => 'view'
    end
  end
  
  
Problems, comments, and suggestions all welcome. jonathan.viney@gmail.com
  
== Credits

Atelier Fabien - Support for :scope =>
Rick Olson - I borrowed some of the testing code from acts_as_versioned
