swanandp/acts_as_list — pull request #91 by fabn (2013-09-09 23:30:03+00:00)
Title: Inverted position support

I've used this gem in a project which require this kind of ordering queries:

```ruby
class Article
acts_as_list top_of_list: 1, add_new_at: :top
default_scope where(active: true).order('publication_date DESC', 'position ASC')
end
```

This could be pretty common if you have a list of items and you want to sort them by two distinct fields (in my case publication day and **then** list position). With this you'll always have new articles as first item by default
but you can reorder them if you wish using the position column.

In this case MySQL generated queries [can't be optimized by MySQL](http://dev.mysql.com/doc/refman/5.5/en/order-by-optimization.html) even if you have indexes on both fields because of `ASC` and `DESC` presence in the same query.

In that case one solution I've found is to use a column with same meaning of `position` but with inverted order, i.e. for every record in the table `position == -inverted_position`. This code will activate this behavior and takes care of updating both columns at the same time.

In this way you will get index optimization by changing the above code to

```ruby
class Article
acts_as_list top_of_list: 1, add_new_at: :top, inverted_position: true
default_scope where(active: true).order('publication_date DESC', 'inverted_position DESC')
end
```

Obviously this option is disabled by default thus existing code wouldn't even notice it.

I've used this code in production for a while and it solved performance issues with that kind of queries.

I'm submitting this PR now because I found a bug some time ago and I had no time to fix it. Further it missed instructions to explain how it works.

Now I've completed those tasks and I'm submitting to your attention for merge.

P.S. tests for this patch use rspec in addition to test unit, [once you told me](https://github.com/swanandp/acts_as_list/pull/51#issuecomment-10177034) that you're interested in porting current tests to rspec, so this could be a good starting point.