I'm using the acts_as_list plugin with rails 3.1 and whenever I add or remove a resource existing positions are ordered and updated fine. However, when updating the position of a resource with update_attributes no reordering seems to take place and I can be left with resources that have duplicated positions. Is this the correct behaviour of acts_as_list?
I've searched for clarification but documentation on this plug in is really limited.
I'm not using javascript at this stage, the position is simply determined with a select box that has an appropriately limited range.
Thanks
There's nothing in the plugin that gets called when the object is updated. You'll have to do it manually using the built-in methods that acts_as_list provides.
The ruby file for this plugin is only 300 lines and easy to follow, it will tell you everything there is to know about acts_as_list... honestly there's not much to it: https://github.com/swanandp/acts_as_list/blob/master/lib/acts_as_list/active_record/acts/list.rb
To do it manually, just get all items with a position higher than the current item and increment each one. This is how I handle it in my apps (not using acts_as_list but the concept is there). This is example is for ordering forums:
forum.rb
PositionOptions = [["First Forum", "-1"]] + all.map{|forum| ["After #{forum.subject}", forum.position]}
attr_accessor :position_before
before_save :set_position, :if => "position_before.present?"
def set_position
self.position = position_before.to_i + 1
end
after_save :do_positions, :if => "position_before.present?"
def do_positions
Forum.where('position >= ? AND id != ?', position, id).order('position, updated_at DESC').all.each_with_index do |forum, index|
forum.update_attribute('position', position + index + 1)
end
end
view
<% position_options = Forum::PositionOptions %>
<%= f.select :position_before, position_options.reject {|forum| @forum.position == forum[1]}, :selected => position_options[position_options.index {|p| p[1] == @forum.position} - 1][1] %>
Maybe not the best way to do it, but it was the best I could come up with. It will probably be too expensive if you plan on the positions being updated often, or if there will be a lot of objects being positioned... but it works for small collections like forums.