mongoid-list 0.4.0 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
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