Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix position when no serial positions #223

Merged
merged 5 commits into from
Aug 21, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 24 additions & 14 deletions lib/acts_as_list/active_record/acts/list.rb
Original file line number Diff line number Diff line change
Expand Up @@ -174,8 +174,12 @@ def move_lower
return unless lower_item

acts_as_list_class.transaction do
lower_item.decrement_position
increment_position
if lower_item.send(position_column) != self.send(position_column)
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just wondering with these methods. Do we need the branching here. Could the first branch not handle all situations (i.e. consecutive numbering and non-consecutive?)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@PoslinskiNet can you answer that ? 😉

Copy link
Contributor

@PoslinskiNet PoslinskiNet Aug 21, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, it is possible, but didn't want to change the default behaviour, just handle "non-consequence" branch, so consider that as a refactor :).

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, yes that makes sense.

swap_positions(lower_item, self)
else
lower_item.decrement_position
increment_position
end
end
end

Expand All @@ -184,8 +188,12 @@ def move_higher
return unless higher_item

acts_as_list_class.transaction do
higher_item.increment_position
decrement_position
if higher_item.send(position_column) != self.send(position_column)
swap_positions(higher_item, self)
else
higher_item.increment_position
decrement_position
end
end
end

Expand Down Expand Up @@ -236,16 +244,14 @@ def decrement_position
set_list_position(self.send(position_column).to_i - 1)
end

# Return +true+ if this object is the first in the list.
def first?
return false unless in_list?
self.send(position_column) == acts_as_list_top
!higher_item
end

# Return +true+ if this object is the last in the list.
def last?
return false unless in_list?
self.send(position_column) == bottom_position_in_list
!lower_item
end

# Return the next higher item in the list.
Expand All @@ -261,9 +267,8 @@ def higher_items(limit=nil)
position_value = send(position_column)
acts_as_list_list.
where("#{quoted_position_column_with_table_name} < ?", position_value).
where("#{quoted_position_column_with_table_name} >= ?", position_value - limit).
limit(limit).
order("#{quoted_position_column_with_table_name} ASC")
order("#{quoted_position_column_with_table_name} DESC").
limit(limit)
end

# Return the next lower item in the list.
Expand All @@ -279,9 +284,8 @@ def lower_items(limit=nil)
position_value = send(position_column)
acts_as_list_list.
where("#{quoted_position_column_with_table_name} > ?", position_value).
where("#{quoted_position_column_with_table_name} <= ?", position_value + limit).
limit(limit).
order("#{quoted_position_column_with_table_name} ASC")
order("#{quoted_position_column_with_table_name} ASC").
limit(limit)
end

# Test if this record is in a list
Expand All @@ -308,6 +312,12 @@ def set_list_position(new_position)
end

private

def swap_positions(item1, item2)
item1.set_list_position(item2.send(position_column))
item2.set_list_position(item1.send("#{position_column}_was"))
end

def acts_as_list_list
acts_as_list_class.unscoped do
acts_as_list_class.where(scope_condition)
Expand Down
30 changes: 28 additions & 2 deletions test/shared_list_sub.rb
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,32 @@ def test_next_prev
assert_nil ListMixin.where(id: 4).first.lower_item
end

def test_next_prev_not_regular_sequence
ListMixin.all.each do |item|
item.update_attributes(pos: item.pos * 5)
end

assert_equal [1, 2, 3, 4], ListMixin.where(parent_id: 5000).order('pos').map(&:id)

ListMixin.where(id: 2).first.move_lower
assert_equal [1, 3, 2, 4], ListMixin.where(parent_id: 5000).order('pos').map(&:id)

ListMixin.where(id: 2).first.move_higher
assert_equal [1, 2, 3, 4], ListMixin.where(parent_id: 5000).order('pos').map(&:id)

ListMixin.where(id: 1).first.move_to_bottom
assert_equal [2, 3, 4, 1], ListMixin.where(parent_id: 5000).order('pos').map(&:id)

ListMixin.where(id: 1).first.move_to_top
assert_equal [1, 2, 3, 4], ListMixin.where(parent_id: 5000).order('pos').map(&:id)

ListMixin.where(id: 2).first.move_to_bottom
assert_equal [1, 3, 4, 2], ListMixin.where(parent_id: 5000).order('pos').map(&:id)

ListMixin.where(id: 4).first.move_to_top
assert_equal [4, 1, 3, 2], ListMixin.where(parent_id: 5000).order('pos').map(&:id)
end

def test_next_prev_groups
li1 = ListMixin.where(id: 1).first
li2 = ListMixin.where(id: 2).first
Expand All @@ -53,9 +79,9 @@ def test_next_prev_groups
assert_equal [li2, li3], li1.lower_items(2)
assert_equal [], li4.lower_items

assert_equal [li1, li2], li3.higher_items
assert_equal [li2, li1], li3.higher_items
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it going to break existing code if the order of returned higher items is in reverse to what it used to be?

assert_equal [li1], li2.higher_items
assert_equal [li2, li3], li4.higher_items(2)
assert_equal [li3, li2], li4.higher_items(2)
assert_equal [], li1.higher_items
end

Expand Down
2 changes: 1 addition & 1 deletion test/test_joined_list.rb
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ def test_higher_items
item1 = Item.create section: section
item2 = Item.create section: section
item3 = Item.create section: section
assert_equal item3.higher_items.visible, [item1, item2]
assert_equal item3.higher_items.visible, [item2, item1]
end

def test_lower_items
Expand Down