Skip to content
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
10 changes: 7 additions & 3 deletions lib/mongoid/orderable/callbacks.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,18 @@ def add_to_list

def remove_from_list
self.orderable_keys.each do |column|
col, pos = orderable_column(column), orderable_position(column)
MongoidOrderable.inc orderable_scoped(column).where(col.gt => pos), col, -1
remove_position_from_list column
end
end

def remove_position_from_list(column)
col, pos = orderable_column(column), orderable_position(column)
MongoidOrderable.inc orderable_scoped(column).where(col.gt => pos), col, -1
end

def apply_position column, target_position
if persisted? && !embedded? && orderable_scope_changed?(column)
self.class.unscoped.find(_id).remove_from_list
self.class.unscoped.find(_id).remove_position_from_list(column)
self.send("orderable_#{column}_position=", nil)
end

Expand Down
60 changes: 60 additions & 0 deletions spec/mongoid/orderable_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,17 @@ class MultipleColumnsOrderable
orderable :column => :groups, :scope => :group
end

class MultipleScopedOrderable
include Mongoid::Document
include Mongoid::Orderable

belongs_to :apple
belongs_to :orange

orderable :column => :posa, :scope => :apple_id
orderable :column => :poso, :scope => :orange_id
end

describe SimpleOrderable do

before :each do
Expand Down Expand Up @@ -1322,4 +1333,53 @@ class Apple
end
end

describe MultipleScopedOrderable do
before :each do
Apple.delete_all; Orange.delete_all;
MultipleScopedOrderable.delete_all

3.times do
Apple.create; Orange.create
end

MultipleScopedOrderable.create! :apple_id => 1, :orange_id => 1
MultipleScopedOrderable.create! :apple_id => 2, :orange_id => 1
MultipleScopedOrderable.create! :apple_id => 2, :orange_id => 2
MultipleScopedOrderable.create! :apple_id => 1, :orange_id => 3
MultipleScopedOrderable.create! :apple_id => 1, :orange_id => 1
MultipleScopedOrderable.create! :apple_id => 3, :orange_id => 3
MultipleScopedOrderable.create! :apple_id => 2, :orange_id => 3
MultipleScopedOrderable.create! :apple_id => 3, :orange_id => 2
MultipleScopedOrderable.create! :apple_id => 1, :orange_id => 3
end

def apple_positions
MultipleScopedOrderable.order_by([:apple_id, :asc], [:posa, :asc]).map(&:posa)
end

def orange_positions
MultipleScopedOrderable.order_by([:orange_id, :asc], [:poso, :asc]).map(&:poso)
end

describe 'default positions' do
it { apple_positions.should == [1, 2, 3, 4, 1, 2, 3, 1, 2] }
it { orange_positions.should == [1, 2, 3, 1, 2, 1, 2, 3, 4] }
end

describe 'change the scope of the apple' do
let(:record) { MultipleScopedOrderable.first }
before do
record.update_attribute(:apple_id, 2)
end

it 'should properly set the apple positions' do
apple_positions.should == [1, 2, 3, 1, 2, 3, 4, 1, 2]
end

it 'should not affect the orange positions' do
orange_positions.should == [1, 2, 3, 1, 2, 1, 2, 3, 4]
end
end
end

end