Skip to content
Browse files

Merge pull request #38 from dubroe/master

Added ability to set item positions directly (e.g. In a form)
  • Loading branch information...
2 parents bf0a4eb + 2c1ca46 commit b7161827583d0d66fd7509f0bf2ebd3ab4b9fffc @swanandp committed Jun 30, 2012
Showing with 24 additions and 4 deletions.
  1. +12 −4 lib/acts_as_list/active_record/acts/list.rb
  2. +12 −0 test/test_list.rb
View
16 lib/acts_as_list/active_record/acts/list.rb
@@ -77,6 +77,7 @@ def position_column
after_destroy :decrement_positions_on_lower_items
before_create :add_to_list_#{configuration[:add_new_at]}
+ after_update :update_positions
EOV
end
end
@@ -276,24 +277,24 @@ def increment_positions_on_all_items
end
# Reorders intermediate items to support moving an item from old_position to new_position.
- def shuffle_positions_on_intermediate_items(old_position, new_position)
+ def shuffle_positions_on_intermediate_items(old_position, new_position, avoid_id = nil)
return if old_position == new_position
-
+ avoid_id_condition = avoid_id ? " AND id != #{avoid_id}" : ''
if old_position < new_position
# Decrement position of intermediate items
#
# e.g., if moving an item from 2 to 5,
# move [3, 4, 5] to [2, 3, 4]
acts_as_list_class.update_all(
- "#{position_column} = (#{position_column} - 1)", "#{scope_condition} AND #{position_column} > #{old_position} AND #{position_column} <= #{new_position}"
+ "#{position_column} = (#{position_column} - 1)", "#{scope_condition} AND #{position_column} > #{old_position} AND #{position_column} <= #{new_position}#{avoid_id_condition}"
)
else
# Increment position of intermediate items
#
# e.g., if moving an item from 5 to 2,
# move [2, 3, 4] to [3, 4, 5]
acts_as_list_class.update_all(
- "#{position_column} = (#{position_column} + 1)", "#{scope_condition} AND #{position_column} >= #{new_position} AND #{position_column} < #{old_position}"
+ "#{position_column} = (#{position_column} + 1)", "#{scope_condition} AND #{position_column} >= #{new_position} AND #{position_column} < #{old_position}#{avoid_id_condition}"
)
end
end
@@ -317,6 +318,13 @@ def store_at_0
decrement_positions_on_lower_items(old_position)
end
end
+
+ def update_positions
+ old_position = send("#{position_column}_was").to_i
+ new_position = send(position_column).to_i
+ return unless acts_as_list_class.where("#{position_column} = #{new_position}").count > 1
+ shuffle_positions_on_intermediate_items old_position, new_position, id
+ end
end
end
end
View
12 test/test_list.rb
@@ -234,6 +234,18 @@ def test_insert_at
new4.reload
assert_equal 4, new4.pos
end
+
+ def test_update_position
+ assert_equal [1, 2, 3, 4], DefaultScopedMixin.find(:all).map(&:id)
+ DefaultScopedMixin.find(2).update_attribute(:pos, 4)
+ assert_equal [1, 3, 4, 2], DefaultScopedMixin.find(:all).map(&:id)
+ DefaultScopedMixin.find(2).update_attribute(:pos, 2)
+ assert_equal [1, 2, 3, 4], DefaultScopedMixin.find(:all).map(&:id)
+ DefaultScopedMixin.find(1).update_attribute(:pos, 4)
+ assert_equal [2, 3, 4, 1], DefaultScopedMixin.find(:all).map(&:id)
+ DefaultScopedMixin.find(1).update_attribute(:pos, 1)
+ assert_equal [1, 2, 3, 4], DefaultScopedMixin.find(:all).map(&:id)
+ end
end

0 comments on commit b716182

Please sign in to comment.
Something went wrong with that request. Please try again.