mongoid-list 0.4.0 → 0.5.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 6d6d233c11d01fef19a74b49979cd597c6b4c9f3
4
- data.tar.gz: 62117736d0330d0a57263bf544cfe2c21aec54ec
3
+ metadata.gz: 940d829ee5548d99991b72e14e1c7d196fc80b11
4
+ data.tar.gz: 7c2672f1c043e6934670ad6f6c940ac5c3aeb330
5
5
  SHA512:
6
- metadata.gz: 24249d8cfa2b9f68858115e941348ef43cbbe95f05e07ddab99498b23e23a95689c1940a93f878f5bd5683a97f77b8be5d71753722ef49cc851989394198e7b4
7
- data.tar.gz: 49b9feaa21091ee4cb4eba631fe28ab0ffd6b1317536be7e8cfdc756e9e5f58febaf35311f0b9daf989da8d3557328606361c4b23bffa1d8aca97a9f9ed2aac5
6
+ metadata.gz: 84f72b562c0e919091cb6ab5420e58d4f3afaab03ee6bad26e0ae041eb7c6bad17ef895f97df3b96dc8d5eafc5905df631794ba8010e0695f3269283332e1838
7
+ data.tar.gz: 67bb545e021632e14a738ec55182b1604eee04df64caad4490e7e7267dff7bfa4b75fd215a18c09b6a74e290aecf36f1c7fa8bc74a7aa5cf70ab79a63f013090
data/Guardfile CHANGED
@@ -2,7 +2,8 @@ guard 'spork', wait: 20 do
2
2
  watch('Gemfile')
3
3
  end
4
4
 
5
- guard :rspec, version: 2 do
6
- watch('spec/spec_helper.rb') { "spec" }
5
+ guard :rspec do
6
+ watch('spec/spec_helper.rb') { "spec" }
7
+ watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" }
7
8
  watch(%r{^spec/.+_spec\.rb})
8
9
  end
data/README.md CHANGED
@@ -22,8 +22,8 @@ class CrowTRobot
22
22
  include Mongoid::Document
23
23
  include Mongoid::List
24
24
 
25
- field :title
26
- slug :title
25
+ lists
26
+
27
27
  end
28
28
  ```
29
29
 
@@ -61,14 +61,14 @@ doc.list_scope_conditions # Additional query conditions for scoped lists.
61
61
  Scoping
62
62
  -------
63
63
 
64
- To scope the list, pass `:scope` on field definition:
64
+ To scope the list, pass `:scope` on lists definition:
65
65
 
66
66
  ```ruby
67
67
  class TomServo
68
68
  include Mongoid::Document
69
- include Mongoid::Slug
69
+ include Mongoid::List
70
70
 
71
- field :position, type: Integer, scope: :satellite_of_love_id
71
+ lists scope: :satellite_of_love_id
72
72
  belongs_to :satellite_of_love
73
73
 
74
74
  end
@@ -1,8 +1,10 @@
1
+ require "mongoid/list"
2
+
1
3
  module Mongoid
2
4
 
3
- Fields.option :scope do |model, field, value|
5
+ # Fields.option :scope do |model, field, value|
4
6
 
5
- end
7
+ # end
6
8
 
7
9
  module List
8
10
 
@@ -12,15 +14,21 @@ module Mongoid
12
14
  autoload :Embedded, 'mongoid/list/embedded'
13
15
 
14
16
  included do
15
- field :position, type: Integer
17
+ attr_accessor :_scope_list_update_to_previous
18
+ class_attribute :mongoid_list_settings
19
+
20
+ self.mongoid_list_settings = { scoped: false, scope: nil }
21
+
22
+ before_create :set_initial_position_in_list
16
23
 
17
- validates :position, numericality: true, on: :update
24
+ before_update :reset_position_between_scopes, if: :list_scope_changing?
18
25
 
19
- before_create :set_initial_position_in_list
20
- before_update :mark_for_update_processing_of_list, if: :position_changed?
21
- after_update :update_positions_in_list!, if: :_process_list_change
22
- before_destroy :mark_for_removal_processing_from_list
23
- after_destroy :update_positions_in_list!, if: :_process_list_change
26
+ before_update :mark_for_update_processing_of_list, if: ->(d){ d.position_changed? && !d.list_scope_changing? }
27
+ before_destroy :mark_for_removal_processing_from_list
28
+
29
+ after_update :clear_list_scope_changing_state
30
+ after_update :update_positions_in_list!, if: :_process_list_change
31
+ after_destroy :update_positions_in_list!, if: :_process_list_change
24
32
 
25
33
  scope :ordered, -> { asc(:position) }
26
34
  end
@@ -28,6 +36,18 @@ module Mongoid
28
36
 
29
37
  module ClassMethods
30
38
 
39
+ def lists(opts={})
40
+
41
+ field :position, type: Integer
42
+
43
+ if opts[:scope].present?
44
+ self.mongoid_list_settings[:scoped] = true
45
+ self.mongoid_list_settings[:scope] = opts[:scope]
46
+ end
47
+
48
+ validates :position, numericality: true, on: :update
49
+ end
50
+
31
51
  def update_positions_in_list!(elements, binding=nil)
32
52
  embedded? ? Embedded.update_positions!(binding, elements) : Collection.update_positions!(self, elements)
33
53
  end
@@ -39,11 +59,11 @@ module Mongoid
39
59
 
40
60
 
41
61
  def list_scoped?
42
- fields["position"].options.has_key?(:scope)
62
+ self.class.mongoid_list_settings[:scoped]
43
63
  end
44
64
 
45
65
  def list_scope_field
46
- fields["position"].options[:scope]
66
+ self.class.mongoid_list_settings[:scope]
47
67
  end
48
68
 
49
69
  def list_scope_value
@@ -54,6 +74,14 @@ module Mongoid
54
74
  list_scoped? ? { list_scope_field.to_sym => list_scope_value } : {}
55
75
  end
56
76
 
77
+ def list_scope_changing_conditions
78
+ { list_scope_field.to_sym => _scope_list_update_to_previous }
79
+ end
80
+
81
+ def list_scope_changing?
82
+ @_list_scope_changing ||= (list_scoped? && changes.keys.include?(list_scope_field.to_s))
83
+ end
84
+
57
85
 
58
86
  private
59
87
 
@@ -62,6 +90,10 @@ module Mongoid
62
90
  self.position = list_count + 1
63
91
  end
64
92
 
93
+ def set_initial_scope_change_position_in_list
94
+ self.position = list_count
95
+ end
96
+
65
97
  def mark_for_update_processing_of_list
66
98
  self._process_list_change = if position_moving_up?
67
99
  { min: position_was, max: position, by: -1 }
@@ -70,6 +102,10 @@ module Mongoid
70
102
  end
71
103
  end
72
104
 
105
+ def clear_processing_of_list
106
+ self._process_list_change = nil
107
+ end
108
+
73
109
  def position_moving_up?
74
110
  position > position_was
75
111
  end
@@ -86,6 +122,34 @@ module Mongoid
86
122
  embedded? ? Embedded.new(self).count : Collection.new(self).count
87
123
  end
88
124
 
125
+ def reset_position_between_scopes
126
+ set_list_scoping_to_previous_value
127
+ move_list_to_new_scope!
128
+ mark_for_removal_processing_from_list
129
+ update_positions_in_list!
130
+ clear_processing_of_list
131
+ clear_list_scoping_from_previous_value
132
+ set_initial_scope_change_position_in_list
133
+ true
134
+ end
135
+
136
+ def move_list_to_new_scope!
137
+ self.set({ list_scope_field => list_scope_value })
138
+ end
139
+
140
+ def set_list_scoping_to_previous_value
141
+ self._scope_list_update_to_previous = changes[list_scope_field.to_s].first
142
+ end
143
+
144
+ def clear_list_scoping_from_previous_value
145
+ self._scope_list_update_to_previous = nil
146
+ end
147
+
148
+ def clear_list_scope_changing_state
149
+ remove_instance_variable(:@_list_scope_changing)
150
+ true
151
+ end
152
+
89
153
  end
90
154
 
91
155
  end
@@ -14,7 +14,11 @@ module Mongoid
14
14
 
15
15
 
16
16
  def conditions
17
- obj.list_scope_conditions
17
+ if obj._scope_list_update_to_previous
18
+ obj.list_scope_changing_conditions
19
+ else
20
+ obj.list_scope_conditions
21
+ end
18
22
  end
19
23
 
20
24
  end
@@ -1,5 +1,5 @@
1
1
  module Mongoid
2
2
  module List
3
- VERSION = "0.4.0"
3
+ VERSION = "0.5.0"
4
4
  end
5
5
  end
@@ -448,8 +448,51 @@ describe Mongoid::List do
448
448
  end
449
449
 
450
450
 
451
- describe "Initializing in multiple scopes" do
451
+ describe "#list_scope_changing_conditions" do
452
+
453
+ subject { Scoped.new }
454
+
455
+ it "uses value in :_scope_list_update_to_previous" do
456
+ subject._scope_list_update_to_previous = "this-is-something-eh"
457
+ subject.list_scope_changing_conditions.should eq \
458
+ ({ group: "this-is-something-eh" })
459
+ end
460
+
461
+ end
462
+
463
+
464
+ describe "#list_scope_changing?" do
465
+
466
+ context "when unscoped" do
467
+
468
+ subject { Simple.create }
469
+ specify { subject.list_scope_changing?.should be_false }
470
+
471
+ end
472
+
473
+ context "when Scoped" do
474
+
475
+ subject { Scoped.create(group: "A") }
476
+
477
+ context "but no change to :group" do
478
+
479
+ specify { subject.list_scope_changing?.should be_false }
452
480
 
481
+ end
482
+
483
+ context "with change to :group" do
484
+
485
+ before { subject.group = "B" }
486
+ specify { subject.list_scope_changing?.should be_true }
487
+
488
+ end
489
+
490
+ end
491
+
492
+ end
493
+
494
+
495
+ describe "Initializing in multiple scopes" do
453
496
 
454
497
  context "on a Collection" do
455
498
 
@@ -651,6 +694,70 @@ describe Mongoid::List do
651
694
 
652
695
  end
653
696
 
697
+ context "changing Scope" do
698
+
699
+ let!(:group1_1) { Scoped.create(group: 1) }
700
+ let!(:group1_2) { Scoped.create(group: 1) }
701
+ let!(:group2_1) { Scoped.create(group: 2) }
702
+ let!(:group2_2) { Scoped.create(group: 2) }
703
+ let!(:group2_3) { Scoped.create(group: 2) }
704
+
705
+ before do
706
+ lambda {
707
+ group2_2.update_attributes(group: 1)
708
+ }.should change(group2_2, :position).from(2).to(3)
709
+ end
710
+
711
+ specify "@group1_1 :position is unchanged" do
712
+ group1_1.position.should eq 1
713
+ group1_1.reload.position.should eq 1
714
+ end
715
+
716
+ specify "@group1_2 :position is unchanged" do
717
+ group1_2.position.should eq 2
718
+ group1_2.reload.position.should eq 2
719
+ end
720
+
721
+ specify "@group2_1 :position is unchanged" do
722
+ group2_1.position.should eq 1
723
+ group2_1.reload.position.should eq 1
724
+ end
725
+
726
+ specify "@group2_3 :position changes to 2" do
727
+ group2_3.position.should eq 3
728
+ group2_3.reload.position.should eq 2
729
+ end
730
+
731
+ end
732
+
733
+ context "missing Scope" do
734
+
735
+ let!(:doc1) { Scoped.create(group: 1) }
736
+ let!(:doc2) { Scoped.create(group: 1) }
737
+ let!(:doc3) { Scoped.create() }
738
+
739
+ specify "initial positions" do
740
+ doc1.position.should eq 1
741
+ doc2.position.should eq 2
742
+ doc3.position.should eq 1
743
+ end
744
+
745
+ end
746
+
747
+ context "removing Scope" do
748
+
749
+ let!(:doc1) { Scoped.create(group: 1) }
750
+ let!(:doc2) { Scoped.create(group: 1) }
751
+ let!(:doc3) { Scoped.create() }
752
+
753
+ it "moves to null scope" do
754
+ lambda { doc1.update_attributes(group: nil); doc1.reload }.should change(doc1, :position).from(1).to(2)
755
+ lambda { doc1.update_attributes(group: nil); doc2.reload }.should change(doc2, :position).from(2).to(1)
756
+ lambda { doc1.update_attributes(group: nil); doc3.reload }.should_not change(doc3, :position)
757
+ end
758
+
759
+ end
760
+
654
761
  end
655
762
 
656
763
 
@@ -20,6 +20,9 @@ Spork.prefork do
20
20
 
21
21
  config.color_enabled = true
22
22
 
23
+ config.filter_run focus: true
24
+ config.run_all_when_everything_filtered = true
25
+
23
26
  config.before(:suite) do
24
27
  Mongoid.load!("mongoid.yml", :test)
25
28
  DatabaseCleaner[:mongoid].strategy = :truncation
@@ -1,6 +1,10 @@
1
1
  class Custom
2
+
2
3
  include Mongoid::Document
3
4
  include Mongoid::List
5
+
4
6
  field :_id, type: String, default: -> { slug }
5
7
  field :slug, type: String
8
+ lists
9
+
6
10
  end
@@ -3,6 +3,8 @@ class Embedded
3
3
  include Mongoid::Document
4
4
  include Mongoid::List
5
5
 
6
+ lists
7
+
6
8
  embedded_in :container
7
9
  embeds_many :items, class_name: 'EmbeddedDeeply'
8
10
 
@@ -3,6 +3,8 @@ class EmbeddedDeeply
3
3
  include Mongoid::Document
4
4
  include Mongoid::List
5
5
 
6
+ lists
7
+
6
8
  embedded_in :embedded
7
9
 
8
10
  end
@@ -4,6 +4,6 @@ class Scoped
4
4
  include Mongoid::List
5
5
 
6
6
  field :group, type: String
7
- field :position, type: Integer, scope: :group
7
+ lists scope: :group
8
8
 
9
9
  end
@@ -6,6 +6,8 @@ class ScopedEmbedded
6
6
  embedded_in :container
7
7
 
8
8
  field :group, type: String
9
- field :position, type: Integer, scope: :group
9
+ # field :position, type: Integer, scope: :group
10
+
11
+ lists scope: :group
10
12
 
11
13
  end
@@ -1,4 +1,8 @@
1
1
  class Simple
2
+
2
3
  include Mongoid::Document
3
4
  include Mongoid::List
5
+
6
+ lists
7
+
4
8
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mongoid-list
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.0
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dave Krupinski
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-02-19 00:00:00.000000000 Z
11
+ date: 2014-03-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: mongoid