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