0.0
No commit activity in last 3 years
No release in over 3 years
This extension provides contiguous positionning capabilities to your ActiveRecord models.
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
 Dependencies

Development

Runtime

 Project Readme

Positionable¶ ↑

<img src=“https://secure.travis-ci.org/pguegan/positionable.png” />

Positionable is a library which provides contiguous positionning capabilities to your ActiveRecord models.

For more functionalities, you could also have a look at acts_as_list.

Installation¶ ↑

Edit your Gemfile, and simply add the following line:

gem 'positionable'

Getting Started¶ ↑

Let’s say you want to make the model Item positionable.

Create a migration¶ ↑

First, create a migration to add the column position to the table items:

rails generate migration add_position_to_items position:integer

Then, run the migration:

rake db:migrate

Setup your model¶ ↑

Simply add the is_positionable method in your ActiveRecord model:

class Item < ActiveRecord::Base
  is_positionable
end

Grouping records¶ ↑

Maybe your items are grouped (typically with a belongs_to association). In this case, you’ll want to restrict the position in each group by declaring the :scope option:

class Item < ActiveRecord::Base
  belongs_to :folder
  is_positionable :scope => :folder
  attr_accessible :folder_id, :position
end

Note that it is the model responsibility to give the white-list of attributes that can be updated via mass-assignement. In this case, you must add the position attribute in the attr_accessible clause.

Start position¶ ↑

By default, position starts by zero. But you may want to change this at the model level, for instance by starting at one (which seems more natural for some people):

class Item < ActiveRecord::Base
  is_positionable :start => 1
end

Ordering¶ ↑

When a new record is created, it is inserted by default at the last (highest) position of its group. Thus, when record are listed, the newly created record will appear at the bottom.

It is possible to change this behaviour by setting the order option as follows:

class Item < ActiveRecord::Base
  is_positionable :order => :desc
end

This way, records are always listed by descending positions order. Record that have the highest position will appears at the top.

Caution! The semantic of next or previous methods remains unchanged. More precisely, even if the highest position is the position of the first returned record, it is still considered as the last one (i.e.: Item.first.last? returns true). I know, this is odd. The semantic of these methods will certainly change in a further version.

Mixing options¶ ↑

Obviously, these options are not exclusive. You are free to mix them like, for example:

class Item < ActiveRecord::Base
  belongs_to :folder
  is_positionable :scope => :folder, :order => :desc, :start => 1
end

Usage¶ ↑

Querying¶ ↑

To get the previous or next sibling items:

previous = item.previous
all_previous = item.all_previous
next = item.next
all_next = item.all_next

Both first and last items can be caracterized:

item.first?   # True if item.previous is nil
item.last?    # True if item.next is nil

Given a positionable item, its position is always included in a range which can be determined as follows:

item.range

If this item is aimed at being moved to another different scope, then you can pass this new scope as a parameter:

item.range(folder)

Moving¶ ↑

Rather than directly assign position attribute, you can move your items with these provided methods:

item = Item.create(...)           # The newly created item is put at the last position (by default).
item.up!                          # Item's position is swaped with the previous item.
item.down!                        # Item's position is swaped with the next item.
item.move_to new_position         # Moves this record to the given position, and updates sibling items positions accordingly.

Yet, it is possible to update the item’s position via mass-assignement:

item.update_attributes { :position => new_position, ... }

This will trigger some ActiveRecord callbacks in order to maintain positions contiguity across all other concerned items, even if the item is moved from a scope to another.