mongoid_orderable 1.2.0 → 4.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,15 @@
1
+ ---
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ Njk2ODJiZDJmM2RiNmY2MTkzNDljNjkzYmI1ZGIzMzI5YzlhNjI1ZQ==
5
+ data.tar.gz: !binary |-
6
+ NjU4ZWExYTdjN2MzOGY0YWQzN2RiMTk1NzI1ODM1NzUyNTdjMDkyNw==
7
+ SHA512:
8
+ metadata.gz: !binary |-
9
+ OWMyZGZkOTliN2MzNmVhOTExMWJkZDI5OTg0MzY0MTcwMjcyY2Q4MzMzZDdh
10
+ OTFkM2Q2NWNkMDQwZGQ0Y2FhZDQ4OTliN2ViMDM2MGJiNGY2M2FkMzI1NWRl
11
+ MjQ1MTM3NjkyNDZmOWYzZTYxYzY2NjI3ODI4OTQwYWJmZmMwNzA=
12
+ data.tar.gz: !binary |-
13
+ ODFjOGIwNDhhMjdjNjk4M2E5MzY2M2JmZDdiMWI2MDgzNWI2M2Y0NDA0YzAz
14
+ Mjg1YmU1OTM3YzgyNDVjZGU2ODdhMWU0YTcxYTc4YzQxYzE0MTRkYWIxYWNk
15
+ ZTU2NThlOGZlMmRjMDc3NGQ4MmVkYjQxYzM4YzY0MzhkZmY1N2E=
data/.travis.yml CHANGED
@@ -1,6 +1,5 @@
1
- script: "bundle exec rake spec"
2
-
3
1
  rvm:
2
+ - 1.8.7
4
3
  - 1.9.2
5
4
  - 1.9.3
6
5
  - ruby-head
@@ -8,11 +7,18 @@ rvm:
8
7
 
9
8
  env:
10
9
  - MONGOID_VERSION=2
11
- - MONGOID_VERSION='~> 3.0.0'
10
+ - MONGOID_VERSION=3
11
+ - MONGOID_VERSION=4
12
12
 
13
13
  matrix:
14
14
  exclude:
15
+ - rvm: 1.8.7
16
+ env: MONGOID_VERSION=3
17
+ - rvm: 1.8.7
18
+ env: MONGOID_VERSION=4
19
+ - rvm: 1.9.2
20
+ env: MONGOID_VERSION=3
15
21
  - rvm: 1.9.2
16
- env: MONGOID_VERSION='~> 3.0.0'
22
+ env: MONGOID_VERSION=4
17
23
 
18
- services: mongodb
24
+ services: mongodb
data/CHANGELOG.md ADDED
@@ -0,0 +1,5 @@
1
+ # 4.0.0
2
+
3
+ * Semantic versioning
4
+ * Added Mongoid 4 support (@dblock)
5
+ * Fixes by @johnnyshields and @zhengjia
data/Gemfile CHANGED
@@ -3,9 +3,13 @@ source "http://rubygems.org"
3
3
  # Specify your gem's dependencies in mongoid_orderable.gemspec
4
4
  gemspec
5
5
 
6
- case version = ENV['MONGOID_VERSION'] || "~> 3.0.0.rc"
6
+ case version = ENV['MONGOID_VERSION'] || "~> 3.1"
7
+ when /4/
8
+ gem "mongoid", :github => 'mongoid/mongoid'
9
+ when /3/
10
+ gem "mongoid", "~> 3.1"
7
11
  when /2/
8
- gem "mongoid", "~> 2.4.0"
12
+ gem "mongoid", "~> 2.8"
9
13
  else
10
14
  gem "mongoid", version
11
15
  end
data/README.md CHANGED
@@ -9,7 +9,7 @@ Mongoid::Orderable is a ordered list implementation for your mongoid models.
9
9
  * It uses native mongo batch increment feature
10
10
  * It supports assignable api
11
11
  * It proper assingns position while moving document between scopes
12
- * It supports both mongoid 2 and 3
12
+ * It supports mongoid 2, 3 and 4
13
13
 
14
14
  # How?
15
15
 
@@ -60,4 +60,4 @@ Fork && Patch && Spec && Push && Pull request.
60
60
 
61
61
  # License
62
62
 
63
- Mongoid::Orderable is released under the MIT license.
63
+ Mongoid::Orderable is released under the MIT license.
data/Rakefile CHANGED
@@ -2,3 +2,5 @@ require "bundler/gem_tasks"
2
2
  require "rspec/core/rake_task"
3
3
 
4
4
  RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => [ :spec ]
@@ -13,7 +13,7 @@ module Mongoid::Orderable
13
13
  configuration.merge! options if options.is_a?(Hash)
14
14
  configuration[:scope] = "#{configuration[:scope]}_id".to_sym if configuration[:scope].is_a?(Symbol) && configuration[:scope].to_s !~ /_id$/
15
15
 
16
- field configuration[:column], :type => Integer
16
+ field configuration[:column], orderable_field_opts(configuration)
17
17
  if configuration[:index]
18
18
  if MongoidOrderable.mongoid2?
19
19
  index configuration[:column]
@@ -40,9 +40,22 @@ module Mongoid::Orderable
40
40
  configuration[:base]
41
41
  end
42
42
 
43
+ self_class = self
44
+ define_method :orderable_inherited_class do
45
+ self_class if configuration[:inherited]
46
+ end
47
+
43
48
  before_save :add_to_list
44
49
  after_destroy :remove_from_list
45
50
  end
51
+
52
+ private
53
+
54
+ def orderable_field_opts(configuration)
55
+ field_opts = { :type => Integer }
56
+ field_opts.merge!(configuration.slice(:as))
57
+ field_opts
58
+ end
46
59
  end
47
60
 
48
61
  def move_to! target_position
@@ -98,7 +111,7 @@ module Mongoid::Orderable
98
111
  end
99
112
 
100
113
  def remove_from_list
101
- orderable_scoped.where(orderable_column.gt => orderable_position).inc(orderable_column, -1)
114
+ MongoidOrderable.inc orderable_scoped.where(orderable_column.gt => orderable_position), orderable_column, -1
102
115
  end
103
116
 
104
117
  private
@@ -115,11 +128,21 @@ private
115
128
  if embedded?
116
129
  send(metadata.inverse).send(metadata.name).orderable_scope(self)
117
130
  else
118
- self.class.orderable_scope(self)
131
+ (orderable_inherited_class || self.class).orderable_scope(self)
119
132
  end
120
133
  end
121
134
 
122
135
  def orderable_scope_changed?
136
+ if Mongoid.respond_to?(:unit_of_work)
137
+ Mongoid.unit_of_work do
138
+ orderable_scope_changed_query
139
+ end
140
+ else
141
+ orderable_scope_changed_query
142
+ end
143
+ end
144
+
145
+ def orderable_scope_changed_query
123
146
  !orderable_scoped.where(:_id => _id).exists?
124
147
  end
125
148
 
@@ -134,10 +157,10 @@ private
134
157
  target_position = target_position_to_position target_position
135
158
 
136
159
  unless in_list?
137
- orderable_scoped.where(orderable_column.gte => target_position).inc(orderable_column, 1)
160
+ MongoidOrderable.inc orderable_scoped.where(orderable_column.gte => target_position), orderable_column, 1
138
161
  else
139
- orderable_scoped.where(orderable_column.gte => target_position, orderable_column.lt => orderable_position).inc(orderable_column, 1) if target_position < orderable_position
140
- orderable_scoped.where(orderable_column.gt => orderable_position, orderable_column.lte => target_position).inc(orderable_column, -1) if target_position > orderable_position
162
+ MongoidOrderable.inc(orderable_scoped.where(orderable_column.gte => target_position, orderable_column.lt => orderable_position), orderable_column, 1) if target_position < orderable_position
163
+ MongoidOrderable.inc(orderable_scoped.where(orderable_column.gt => orderable_position, orderable_column.lte => target_position), orderable_column, -1) if target_position > orderable_position
141
164
  end
142
165
 
143
166
  self.orderable_position = target_position
@@ -1,6 +1,17 @@
1
1
  module MongoidOrderable
2
2
  def self.mongoid2?
3
- Mongoid.const_defined? :Contexts
3
+ ::Mongoid.const_defined? :Contexts
4
+ end
5
+ def self.mongoid3?
6
+ ::Mongoid.const_defined? :Observer
7
+ end
8
+
9
+ def self.inc instance, attribute, value
10
+ if MongoidOrderable.mongoid2? || MongoidOrderable.mongoid3?
11
+ instance.inc attribute, value
12
+ else
13
+ instance.inc(attribute => value)
14
+ end
4
15
  end
5
16
  end
6
17
 
@@ -4,7 +4,7 @@ module MongoidOrderable #:nodoc:
4
4
  module Enumerable #:nodoc:
5
5
  def inc attribute, value
6
6
  iterate do |doc|
7
- doc.inc(attribute, value)
7
+ MongoidOrderable.inc doc, attribute, value
8
8
  end
9
9
  end
10
10
  end
@@ -2,9 +2,9 @@ module MongoidOrderable #:nodoc:
2
2
  module Mongoid #:nodoc:
3
3
  module Contextual #:nodoc:
4
4
  module Memory #:nodoc:
5
- def inc attribute, value
5
+ def inc(* args)
6
6
  each do |document|
7
- document.inc(attribute, value)
7
+ document.inc *args
8
8
  end
9
9
  end
10
10
  end
@@ -1,3 +1,3 @@
1
1
  module MongoidOrderable
2
- VERSION = "1.2.0"
2
+ VERSION = '4.0.0'
3
3
  end
@@ -1,6 +1,7 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe Mongoid::Orderable do
4
+
4
5
  class SimpleOrderable
5
6
  include Mongoid::Document
6
7
  include Mongoid::Orderable
@@ -18,6 +19,7 @@ describe Mongoid::Orderable do
18
19
  include Mongoid::Document
19
20
  include Mongoid::Orderable
20
21
 
22
+ field :group_id
21
23
  belongs_to :scoped_group
22
24
 
23
25
  orderable :scope => :group
@@ -42,7 +44,7 @@ describe Mongoid::Orderable do
42
44
  include Mongoid::Document
43
45
  include Mongoid::Orderable
44
46
 
45
- orderable :column => :pos
47
+ orderable :column => :pos, :as => :my_position
46
48
  end
47
49
 
48
50
  class NoIndexOrderable
@@ -59,7 +61,21 @@ describe Mongoid::Orderable do
59
61
  orderable :base => 0
60
62
  end
61
63
 
64
+ class Fruit
65
+ include Mongoid::Document
66
+ include Mongoid::Orderable
67
+
68
+ orderable :inherited => true
69
+ end
70
+
71
+ class Apple < Fruit
72
+ end
73
+
74
+ class Orange < Fruit
75
+ end
76
+
62
77
  describe SimpleOrderable do
78
+
63
79
  before :each do
64
80
  SimpleOrderable.delete_all
65
81
  5.times do
@@ -79,8 +95,10 @@ describe Mongoid::Orderable do
79
95
  it 'should have index on position column' do
80
96
  if MongoidOrderable.mongoid2?
81
97
  SimpleOrderable.index_options[:position].should_not be_nil
82
- else
98
+ elsif MongoidOrderable.mongoid3?
83
99
  SimpleOrderable.index_options[{:position => 1}].should_not be_nil
100
+ else
101
+ SimpleOrderable.index_specifications.detect { |spec| spec.key == {:position => 1} }.should_not be_nil
84
102
  end
85
103
  end
86
104
 
@@ -108,7 +126,6 @@ describe Mongoid::Orderable do
108
126
  SimpleOrderable.where(:position => 3).destroy
109
127
  positions.should == [1, 2, 3, 4]
110
128
  end
111
-
112
129
  end
113
130
 
114
131
  describe 'inserting' do
@@ -130,7 +147,6 @@ describe Mongoid::Orderable do
130
147
  positions.should == [1, 2, 3, 4, 5, 6]
131
148
  newbie.position.should == 4
132
149
  end
133
-
134
150
  end
135
151
 
136
152
  describe 'movement' do
@@ -177,18 +193,17 @@ describe Mongoid::Orderable do
177
193
  record.reload.position.should == 4
178
194
  end
179
195
 
180
- it "does nothing if position not change" do
196
+ it 'does nothing if position not change' do
181
197
  record = SimpleOrderable.where(:position => 3).first
182
198
  record.save
183
199
  positions.should == [1, 2, 3, 4, 5]
184
200
  record.reload.position.should == 3
185
201
  end
186
-
187
202
  end
188
-
189
203
  end
190
204
 
191
205
  describe ScopedOrderable do
206
+
192
207
  before :each do
193
208
  ScopedOrderable.delete_all
194
209
  2.times do
@@ -223,7 +238,6 @@ describe Mongoid::Orderable do
223
238
  ScopedOrderable.where(:position => 2, :group_id => 2).destroy
224
239
  positions.should == [1, 2, 1, 2]
225
240
  end
226
-
227
241
  end
228
242
 
229
243
  describe 'inserting' do
@@ -245,30 +259,72 @@ describe Mongoid::Orderable do
245
259
  positions.should == [1, 2, 1, 2, 3, 4]
246
260
  newbie.position.should == 2
247
261
  end
248
-
249
262
  end
250
263
 
251
- describe "scope movement" do
264
+ describe 'scope movement' do
252
265
 
253
- it "without point on position" do
254
- record = ScopedOrderable.where(:group_id => 2, :position => 2).first
255
- record.update_attributes :group_id => 1
256
- positions.should == [1, 2, 3, 1, 2]
257
- record.reload.position.should == 3
258
- end
266
+ let(:record){ ScopedOrderable.where(:group_id => 2, :position => 2).first }
259
267
 
260
- it "with point on position" do
261
- record = ScopedOrderable.where(:group_id => 2, :position => 2).first
262
- record.update_attributes :group_id => 1, :move_to => :top
263
- positions.should == [1, 2, 3, 1, 2]
264
- record.reload.position.should == 1
268
+ it 'to a new scope group' do
269
+ record.update_attributes :group_id => 3
270
+ positions.should == [1, 2, 1, 2, 1]
271
+ record.position.should == 1
265
272
  end
266
273
 
274
+ context 'when moving to an existing scope group' do
275
+
276
+ it 'without a position' do
277
+ record.update_attributes :group_id => 1
278
+ positions.should == [1, 2, 3, 1, 2]
279
+ record.reload.position.should == 3
280
+ end
281
+
282
+ it 'with symbol position' do
283
+ record.update_attributes :group_id => 1, :move_to => :top
284
+ positions.should == [1, 2, 3, 1, 2]
285
+ record.reload.position.should == 1
286
+ end
287
+
288
+ it 'with point position' do
289
+ record.update_attributes :group_id => 1, :move_to => 2
290
+ positions.should == [1, 2, 3, 1, 2]
291
+ record.reload.position.should == 2
292
+ end
293
+ end
267
294
  end
268
295
 
296
+ if defined?(Mongoid::IdentityMap)
297
+
298
+ context 'when identity map is enabled' do
299
+
300
+ let(:record){ ScopedOrderable.where(:group_id => 2, :position => 2).first }
301
+
302
+ before do
303
+ Mongoid.identity_map_enabled = true
304
+ Mongoid::IdentityMap[ScopedOrderable.collection_name] = { record.id => record }
305
+ end
306
+
307
+ after do
308
+ Mongoid.identity_map_enabled = false
309
+ end
310
+
311
+ it 'to a new scope group' do
312
+ record.update_attributes :group_id => 3
313
+ positions.should == [1, 2, 1, 2, 1]
314
+ record.position.should == 1
315
+ end
316
+
317
+ it 'to an existing scope group' do
318
+ record.update_attributes :group_id => 1, :move_to => 2
319
+ positions.should == [1, 2, 3, 1, 2]
320
+ record.reload.position.should == 2
321
+ end
322
+ end
323
+ end
269
324
  end
270
325
 
271
326
  describe EmbeddedOrderable do
327
+
272
328
  before :each do
273
329
  EmbedsOrderable.delete_all
274
330
  eo = EmbedsOrderable.create!
@@ -285,13 +341,20 @@ describe Mongoid::Orderable do
285
341
  EmbedsOrderable.order_by(:position => 1).all.map { |eo| eo.embedded_orderables.map(&:position).sort }
286
342
  end
287
343
 
288
- it 'should set proper position while creation' do
344
+ it 'sets proper position while creation' do
289
345
  positions.should == [[1, 2], [1, 2, 3]]
290
346
  end
291
347
 
348
+ it 'moves an item returned by a query to position' do
349
+ embedded_orderable_1 = EmbedsOrderable.first.embedded_orderables.where(:position => 1).first
350
+ embedded_orderable_2 = EmbedsOrderable.first.embedded_orderables.where(:position => 2).first
351
+ embedded_orderable_1.move_to! 2
352
+ embedded_orderable_2.reload.position.should == 1
353
+ end
292
354
  end
293
355
 
294
356
  describe CustomizedOrderable do
357
+
295
358
  it 'does not have default position field' do
296
359
  CustomizedOrderable.fields.should_not have_key('position')
297
360
  end
@@ -299,16 +362,27 @@ describe Mongoid::Orderable do
299
362
  it 'should have custom pos field' do
300
363
  CustomizedOrderable.fields.should have_key('pos')
301
364
  end
365
+
366
+ it 'should have an alias my_position which points to pos field on Mongoid 3+' do
367
+ if CustomizedOrderable.respond_to?(:database_field_name)
368
+ CustomizedOrderable.database_field_name('my_position').should eq('pos')
369
+ end
370
+ end
302
371
  end
303
372
 
304
373
  describe NoIndexOrderable do
374
+
305
375
  it 'should not have index on position column' do
306
- NoIndexOrderable.index_options[:position].should be_nil
376
+ if MongoidOrderable.mongoid2? || MongoidOrderable.mongoid3?
377
+ NoIndexOrderable.index_options[:position].should be_nil
378
+ else
379
+ NoIndexOrderable.index_specifications.detect { |spec| spec.key == :position }.should be_nil
380
+ end
307
381
  end
308
382
  end
309
383
 
310
-
311
384
  describe ZeroBasedOrderable do
385
+
312
386
  before :each do
313
387
  ZeroBasedOrderable.delete_all
314
388
  5.times do
@@ -344,7 +418,6 @@ describe Mongoid::Orderable do
344
418
  ZeroBasedOrderable.where(:position => 2).destroy
345
419
  positions.should == [0, 1, 2, 3]
346
420
  end
347
-
348
421
  end
349
422
 
350
423
  describe 'inserting' do
@@ -366,7 +439,6 @@ describe Mongoid::Orderable do
366
439
  positions.should == [0, 1, 2, 3, 4, 5]
367
440
  newbie.position.should == 3
368
441
  end
369
-
370
442
  end
371
443
 
372
444
  describe 'movement' do
@@ -413,15 +485,22 @@ describe Mongoid::Orderable do
413
485
  record.reload.position.should == 3
414
486
  end
415
487
 
416
- it "does nothing if position not change" do
488
+ it 'does nothing if position not change' do
417
489
  record = ZeroBasedOrderable.where(:position => 3).first
418
490
  record.save
419
491
  positions.should == [0, 1, 2, 3, 4]
420
492
  record.reload.position.should == 3
421
493
  end
422
-
423
494
  end
424
-
425
495
  end
426
496
 
497
+ describe Fruit do
498
+
499
+ it 'should set proper position' do
500
+ fruit1 = Apple.create
501
+ fruit2 = Orange.create
502
+ fruit1.position.should == 1
503
+ fruit2.position.should == 2
504
+ end
505
+ end
427
506
  end
metadata CHANGED
@@ -1,20 +1,18 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mongoid_orderable
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.0
5
- prerelease:
4
+ version: 4.0.0
6
5
  platform: ruby
7
6
  authors:
8
7
  - pyromaniac
9
8
  autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
- date: 2013-01-10 00:00:00.000000000 Z
11
+ date: 2013-10-22 00:00:00.000000000 Z
13
12
  dependencies:
14
13
  - !ruby/object:Gem::Dependency
15
14
  name: rake
16
15
  requirement: !ruby/object:Gem::Requirement
17
- none: false
18
16
  requirements:
19
17
  - - ! '>='
20
18
  - !ruby/object:Gem::Version
@@ -22,7 +20,6 @@ dependencies:
22
20
  type: :development
23
21
  prerelease: false
24
22
  version_requirements: !ruby/object:Gem::Requirement
25
- none: false
26
23
  requirements:
27
24
  - - ! '>='
28
25
  - !ruby/object:Gem::Version
@@ -30,7 +27,6 @@ dependencies:
30
27
  - !ruby/object:Gem::Dependency
31
28
  name: rspec
32
29
  requirement: !ruby/object:Gem::Requirement
33
- none: false
34
30
  requirements:
35
31
  - - ! '>='
36
32
  - !ruby/object:Gem::Version
@@ -38,7 +34,6 @@ dependencies:
38
34
  type: :development
39
35
  prerelease: false
40
36
  version_requirements: !ruby/object:Gem::Requirement
41
- none: false
42
37
  requirements:
43
38
  - - ! '>='
44
39
  - !ruby/object:Gem::Version
@@ -46,7 +41,6 @@ dependencies:
46
41
  - !ruby/object:Gem::Dependency
47
42
  name: mongoid
48
43
  requirement: !ruby/object:Gem::Requirement
49
- none: false
50
44
  requirements:
51
45
  - - ! '>='
52
46
  - !ruby/object:Gem::Version
@@ -54,7 +48,6 @@ dependencies:
54
48
  type: :runtime
55
49
  prerelease: false
56
50
  version_requirements: !ruby/object:Gem::Requirement
57
- none: false
58
51
  requirements:
59
52
  - - ! '>='
60
53
  - !ruby/object:Gem::Version
@@ -70,6 +63,7 @@ files:
70
63
  - .rspec
71
64
  - .rvmrc
72
65
  - .travis.yml
66
+ - CHANGELOG.md
73
67
  - Gemfile
74
68
  - README.md
75
69
  - Rakefile
@@ -85,33 +79,26 @@ files:
85
79
  - spec/spec_helper.rb
86
80
  homepage: ''
87
81
  licenses: []
82
+ metadata: {}
88
83
  post_install_message:
89
84
  rdoc_options: []
90
85
  require_paths:
91
86
  - lib
92
87
  required_ruby_version: !ruby/object:Gem::Requirement
93
- none: false
94
88
  requirements:
95
89
  - - ! '>='
96
90
  - !ruby/object:Gem::Version
97
91
  version: '0'
98
- segments:
99
- - 0
100
- hash: 796603552408515910
101
92
  required_rubygems_version: !ruby/object:Gem::Requirement
102
- none: false
103
93
  requirements:
104
94
  - - ! '>='
105
95
  - !ruby/object:Gem::Version
106
96
  version: '0'
107
- segments:
108
- - 0
109
- hash: 796603552408515910
110
97
  requirements: []
111
98
  rubyforge_project: mongoid_orderable
112
- rubygems_version: 1.8.24
99
+ rubygems_version: 2.1.9
113
100
  signing_key:
114
- specification_version: 3
101
+ specification_version: 4
115
102
  summary: Acts as list mongoid implementation
116
103
  test_files:
117
104
  - spec/mongoid/orderable_spec.rb