Get updates

Scott Q&A: What Methods are Available with acts_as_list?

When you make use of Active Record’s convenient acts_as_list modifier in Rails, what does this do for you? Most of the info out there describes the way acts_as_list manages position of items, ordering them like items in a, well, ordered list.

That’s great, but what about new helper methods provided by acts_as_list? Doesn’t it make juggling list items easier? Or do you simply have to fend for yourself when you want to rearrange your list?

Question: What additional methods are provided when using acts_as_list?

Answer: After some digging, I located this list of acts_as_list public methods.

Most of these are easy enough to understand, but I was looking specifically for the magic bullet that allows an item to be moved to a desired spot in the list. Turns out that insert_at does the trick, despite the suggestion that perhaps it was meant instead to operate only on new items. Its code uses insert_at_position (in activerecord/lib/active_record/acts/list.rb) which looks like this:

def insert_at_position(position)
  self.update_attribute(position_column, position)

I had to dissect it to ensure it did precisely what I needed; remove_from_list sounds bad but is really just pulling the item out of position and moving lower items (those between it and the end of the list) up a notch to fill the gap:

def remove_from_list
  decrement_positions_on_lower_items if in_list?

The second line of insert_at_position creates a new gap at the desired position, then the method finishes by setting the item’s position to fill that gap.

Now the only question left in my mind is why the Rails developers decided to have acts_as_list start counting position at 1, when this inevitably leads to “+ 1” expressions littered through code, trying to compensate for id attributes and array indices that count from 0. We’re programmers, we know how to count from zero (one hopes)!

One Response to “Q&A: What Methods are Available with acts_as_list?”

  1. Thanmk you for your comment on the position starting with 1. I wonder if anyone else stumbled over this problem: I’m working on an application which shares a database with a Java application based on Hibernate. While this is surprisingly well going in most areas, Hiibernate also supports ordered collections which (naturally) count from zero. Here we are. The Java app is the legacy one and although Hibernate could define an index base other than zero I’m bound to this value. It would have been a nice thing if acts_as_list had provided the same freedom of choice. Now I must implement some nasty workaround.

Leave a Reply