mongoid_embedded_helper 0.1.2 → 0.2.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.
- data/README.markdown +43 -2
- data/VERSION +1 -1
- data/lib/mongoid/embedded_helper.rb +45 -16
- data/mongoid_embedded_helper.gemspec +1 -1
- data/spec/mongoid/embedded_helper_spec.rb +41 -2
- metadata +2 -2
data/README.markdown
CHANGED
@@ -13,7 +13,7 @@ Mongoid doesn't allow you to perform direct queries on an embedded collection. Y
|
|
13
13
|
To overcome this limitation, use the EmbeddedHelper module to add a method <code>query_class</code> which will find the closest non-embedded node in the hierarchy and
|
14
14
|
then traverse down the path back to the object, so that you can perform the query on the embedded collection.
|
15
15
|
|
16
|
-
<
|
16
|
+
<pre>
|
17
17
|
require 'mongoid_embedded_helper'
|
18
18
|
|
19
19
|
class Item
|
@@ -29,7 +29,48 @@ end
|
|
29
29
|
item = @person.lists[0].items[0]
|
30
30
|
item.query_class.where(:number.gt => 1).to_a
|
31
31
|
|
32
|
-
</
|
32
|
+
</pre>
|
33
|
+
|
34
|
+
## Adjust!
|
35
|
+
|
36
|
+
An as added bonus, an extra adjust! method has been added to Document, Criteria and Array. This enables multi-mutation of attributes!
|
37
|
+
|
38
|
+
*Here an example using a number*
|
39
|
+
<pre>
|
40
|
+
it "should times all positions (greater than 1) by 2" do
|
41
|
+
result = @person.lists[0].items.where(:pos.gt => 1).adjust!(:pos => lambda {|e| e * 2})
|
42
|
+
result.map(&:pos).should == [4, 6]
|
43
|
+
end
|
44
|
+
</pre>
|
45
|
+
|
46
|
+
Passing a number is a convenience shortcut for adding a number instead of having to use the Proc approach as shown below.
|
47
|
+
|
48
|
+
*Here an example using a lambda (or Proc):*
|
49
|
+
<pre>
|
50
|
+
it "should times all positions (greater than 1) by 2" do
|
51
|
+
result = @person.lists[0].items.where(:pos.gt => 1).adjust!(:pos => lambda {|e| e * 2})
|
52
|
+
result.map(&:pos).should == [4, 6]
|
53
|
+
end
|
54
|
+
</pre>
|
55
|
+
|
56
|
+
The Proc approach can in simple cases be declared using a shortcut Symbol/String approach
|
57
|
+
|
58
|
+
*Here an example using a symbol :upcase to declare that the method #upcase should be used as the mutator:*
|
59
|
+
<pre>
|
60
|
+
it "should upcase the name - using symbol arg" do
|
61
|
+
result = @person.adjust!(:name => :upcase)
|
62
|
+
result.name.should == 'Kristian'.upcase
|
63
|
+
end
|
64
|
+
</pre>
|
65
|
+
|
66
|
+
*And using a String 'upcase' instead of a symbol:*
|
67
|
+
<pre>
|
68
|
+
it "should upcase the name - using symbol arg" do
|
69
|
+
result = @person.adjust!(:name => 'upcase')
|
70
|
+
result.name.should == 'Kristian'.upcase
|
71
|
+
end
|
72
|
+
</pre>
|
73
|
+
|
33
74
|
|
34
75
|
## Copyright ##
|
35
76
|
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.2.0
|
@@ -70,29 +70,58 @@ module Mongoid::Document
|
|
70
70
|
def adjust!(attrs = {})
|
71
71
|
run_callbacks(:before_update)
|
72
72
|
(attrs || {}).each_pair do |key, value|
|
73
|
-
next if !value.integer? # only add integer values
|
74
73
|
next if !present? key # only add to properties already present!
|
75
|
-
|
76
|
-
if
|
77
|
-
|
78
|
-
|
79
|
-
if current_val.integer?
|
80
|
-
@attributes[key.to_s] = current_val + value
|
81
|
-
end
|
82
|
-
|
83
|
-
elsif write_allowed?(key)
|
84
|
-
current_val = send("#{key}") || 0
|
85
|
-
|
86
|
-
if current_val.integer?
|
87
|
-
send("#{key}=", current_val + value)
|
88
|
-
end
|
89
|
-
end
|
74
|
+
adjust_by_proc!(key, value) if value.kind_of?(Proc)
|
75
|
+
adjust_by_symbol!(key, value) if value.kind_of?(Symbol) || value.kind_of?(String)
|
76
|
+
adjust_by_number!(key, value) if value.kind_of?(Numeric) # only add integer values
|
90
77
|
end
|
91
78
|
identify if id.blank?
|
92
79
|
notify
|
93
80
|
run_callbacks(:after_update)
|
94
81
|
self
|
82
|
+
end
|
83
|
+
|
84
|
+
private
|
85
|
+
|
86
|
+
def adjust_by_proc! key, proc
|
87
|
+
if set_allowed?(key)
|
88
|
+
current_val = @attributes[key.to_s]
|
89
|
+
@attributes[key.to_s] = proc.call(current_val)
|
90
|
+
elsif write_allowed?(key)
|
91
|
+
current_val = send("#{key}")
|
92
|
+
send("#{key}=", proc.call(current_val))
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
def adjust_by_symbol! key, name
|
97
|
+
method = name.to_sym
|
98
|
+
if set_allowed?(key)
|
99
|
+
current_val = @attributes[key.to_s]
|
100
|
+
@attributes[key.to_s] = current_val.send(method)
|
101
|
+
elsif write_allowed?(key)
|
102
|
+
current_val = send("#{key}")
|
103
|
+
send("#{key}=", current_val.send(method))
|
104
|
+
end
|
95
105
|
end
|
106
|
+
|
107
|
+
|
108
|
+
def adjust_by_number! key, value
|
109
|
+
if set_allowed?(key)
|
110
|
+
current_val = @attributes[key.to_s] || 0
|
111
|
+
|
112
|
+
if current_val.kind_of? Numeric
|
113
|
+
@attributes[key.to_s] = current_val + value
|
114
|
+
end
|
115
|
+
|
116
|
+
elsif write_allowed?(key)
|
117
|
+
current_val = send("#{key}") || 0
|
118
|
+
|
119
|
+
if current_val.kind_of? Numeric
|
120
|
+
send("#{key}=", current_val + value)
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
96
125
|
end
|
97
126
|
|
98
127
|
class Array
|
@@ -78,7 +78,7 @@ describe 'Mongoid Embedded Helper' do
|
|
78
78
|
end
|
79
79
|
end
|
80
80
|
|
81
|
-
describe '#adjust!' do
|
81
|
+
describe '#adjust! numeric' do
|
82
82
|
context 'on an array' do
|
83
83
|
it "should add 1 to all positions greater than 1" do
|
84
84
|
result = @person.lists[0].items.where(:pos.gt => 1).to_a.adjust!(:pos => 1)
|
@@ -105,7 +105,46 @@ describe 'Mongoid Embedded Helper' do
|
|
105
105
|
result = @person.adjust!(:pos => 1)
|
106
106
|
lambda {result.pos}.should raise_error
|
107
107
|
end
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
describe '#adjust! by proc' do
|
112
|
+
context 'on an array' do
|
113
|
+
it "should times all positions (greater than 1) by 2" do
|
114
|
+
result = @person.lists[0].items.where(:pos.gt => 1).to_a.adjust!(:pos => lambda {|e| e * 2})
|
115
|
+
result.map(&:pos).should == [4, 6]
|
116
|
+
end
|
108
117
|
end
|
109
|
-
|
118
|
+
|
119
|
+
context 'on a criteria' do
|
120
|
+
it "should times all positions (greater than 1) by 2" do
|
121
|
+
result = @person.lists[0].items.where(:pos.gt => 1).adjust!(:pos => lambda {|e| e * 2})
|
122
|
+
result.map(&:pos).should == [4, 6]
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
context 'on a document with a name field' do
|
127
|
+
it "should upcase the name" do
|
128
|
+
result = @person.adjust!(:name => lambda {|e| e.upcase })
|
129
|
+
result.name.should == 'Kristian'.upcase
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
describe '#adjust! by symbol and string' do
|
135
|
+
context 'on a document with a name field' do
|
136
|
+
it "should upcase the name - using string arg" do
|
137
|
+
result = @person.adjust!(:name => 'upcase')
|
138
|
+
result.name.should == 'Kristian'.upcase
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
context 'on a document with a name field' do
|
143
|
+
it "should upcase the name - using symbol arg" do
|
144
|
+
result = @person.adjust!(:name => :upcase)
|
145
|
+
result.name.should == 'Kristian'.upcase
|
146
|
+
end
|
147
|
+
end
|
148
|
+
end
|
110
149
|
end
|
111
150
|
|