mongoid_orderable 1.2.0 → 4.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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