Bug in acts_as_list remove_from_list
The error found:
Patch to fix a two problems with acts in list:
- Removing an item from the list does not remove it from the list and returns true to in_list?
- Removing an item from the list and then destroying the item shifts all lower items up two positions, creating duplicates
Console example of the first error:
>> foo = Foo.create()
=> #<Foo:0x6979ab8 SNIP>
>> foo.in_list?
=> true
>> foo.remove_from_list
=> 0
>> foo.in_list?
=> true
>> foo.reload
=> #<Foo:0x6979ab8 SNIP>
>> foo.in_list?
=> true
For the demonstration of the second error, see the failing tests.
Handling
1. in_list? checks for nil in the position column. Handling is to set position to nil when you remove an instance from the list.
2. Also, only remove from list if the item is in list, wrapped this in an if in_list?.
3. This then breaks destroy as you can't nil a frozen hash. So I moved remove_from_list from after_destroy to before_destroy.
Tests
Three tests showing this are attached with the source code to patch it (5 lines in acts/list.rb)