mongoid_monkey 0.1.4 → 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.
- checksums.yaml +4 -4
- data/README.md +9 -4
- data/lib/mongoid_monkey.rb +1 -0
- data/lib/patches/only_pluck_localized.rb +74 -0
- data/lib/version.rb +1 -1
- data/spec/unit/only_pluck_localized.rb +326 -0
- metadata +6 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 118a2a99faa547a7a3336586d933db15563d8069
|
4
|
+
data.tar.gz: 97f311b750030497fd6c1a63da61d369bbcfbdb1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0a3e0791c5012535b304f706f4484c781c2230d6b9ceabde4d39100de8512aef245c02063be791cb8e52734516be7cd50221bd6037dd223b38942ec922c147cd
|
7
|
+
data.tar.gz: b84df91ff37ffbea35e9dc2d559ec7a5cd0aa20d063caf5d583011a6e33c0e9fc307201eec53bba9fe0e3667653448bd3d32bb493c44168bc2f8950137019b6a
|
data/README.md
CHANGED
@@ -25,13 +25,18 @@ Installing this gem will apply all monkey patches for the Mongoid version you ar
|
|
25
25
|
If you would only like some of the patches, please copy and paste the code to your app directly
|
26
26
|
(e.g. `/config/initializers` if using Rails.)
|
27
27
|
|
28
|
+
`●` = This gem adds support
|
29
|
+
`×` = This gem does not yet support (PRs welcome!)
|
30
|
+
`○` = Already supported natively
|
31
|
+
|
28
32
|
| File | Description | 3 | 4 | 5 |
|
29
33
|
| --- | --- | --- | --- | --- |
|
30
|
-
| `atomic.rb` | Backport syntax change of atomic query methods. | ● | | |
|
34
|
+
| `atomic.rb` | Backport syntax change of atomic query methods. | ● | ○ | ○ |
|
31
35
|
| `big_decimal.rb` | Fixes buggy BigDecimal behavior. | ● | ● | ● |
|
32
|
-
| `db_commands.rb` | Use MongoDB 3.0+ command syntax; required for WiredTiger. | ● | ● | |
|
33
|
-
| `instrument.rb` | Backport instrumentation change to Moped 1. | ● | | |
|
34
|
-
| `reorder.rb` | Backport `Criteria#reorder` method. | ● | | |
|
36
|
+
| `db_commands.rb` | Use MongoDB 3.0+ command syntax; required for WiredTiger. | ● | ● | ○ |
|
37
|
+
| `instrument.rb` | Backport instrumentation change to Moped 1. | ● | ○ | ○ |
|
38
|
+
| `reorder.rb` | Backport `Criteria#reorder` method from Mongoid 4. | ● | ○ | ○ |
|
39
|
+
| `only_pluck_localized.rb` | Backport [PR #4299](https://github.com/mongodb/mongoid/pull/4299) from Mongoid 6 which fixes `#only`, `#without`, and `#pluck` with localized fields. | ● | × | × |
|
35
40
|
|
36
41
|
### License
|
37
42
|
|
data/lib/mongoid_monkey.rb
CHANGED
@@ -0,0 +1,74 @@
|
|
1
|
+
# Backport of https://github.com/mongodb/mongoid/pull/4299 Mongoid 6 to Mongoid 3.
|
2
|
+
|
3
|
+
if Mongoid::VERSION =~ /\A3\./
|
4
|
+
|
5
|
+
module Origin
|
6
|
+
class Options < Smash
|
7
|
+
|
8
|
+
def store(key, value, localize = true)
|
9
|
+
super(key, evolve(value, localize))
|
10
|
+
end
|
11
|
+
alias :[]= :store
|
12
|
+
|
13
|
+
private
|
14
|
+
|
15
|
+
def evolve(value, localize = true)
|
16
|
+
case value
|
17
|
+
when Hash
|
18
|
+
evolve_hash(value, localize)
|
19
|
+
else
|
20
|
+
value
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def evolve_hash(value, localize = true)
|
25
|
+
value.inject({}) do |hash, (field, _value)|
|
26
|
+
name, serializer = storage_pair(field)
|
27
|
+
name = normalized_key(name, serializer) if localize
|
28
|
+
hash[name] = _value
|
29
|
+
hash
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
module Origin
|
36
|
+
module Optional
|
37
|
+
|
38
|
+
def only(*args)
|
39
|
+
args = args.flatten
|
40
|
+
puts args.inspect
|
41
|
+
option(*args) do |options|
|
42
|
+
options.store(
|
43
|
+
:fields,
|
44
|
+
args.inject({}){ |sub, field| sub.tap { sub[field] = 1 }},
|
45
|
+
false
|
46
|
+
)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def without(*args)
|
51
|
+
args = args.flatten
|
52
|
+
option(*args) do |options|
|
53
|
+
options.store(
|
54
|
+
:fields,
|
55
|
+
args.inject({}){ |sub, field| sub.tap { sub[field] = 0 }},
|
56
|
+
false
|
57
|
+
)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
module Mongoid
|
64
|
+
module Contextual
|
65
|
+
class Mongo
|
66
|
+
|
67
|
+
def pluck(field)
|
68
|
+
normalized = klass.database_field_name(field)
|
69
|
+
query.dup.select(normalized => 1).map{ |doc| doc[normalized.partition('.').first] }.compact
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
data/lib/version.rb
CHANGED
@@ -0,0 +1,326 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
if defined?(Moped) && Moped::VERSION =~ /\A3\./
|
4
|
+
|
5
|
+
describe Mongoid::Criteria do
|
6
|
+
|
7
|
+
describe "#only" do
|
8
|
+
|
9
|
+
let!(:band) do
|
10
|
+
Band.create(name: "Depeche Mode", likes: 3, views: 10)
|
11
|
+
end
|
12
|
+
|
13
|
+
context "when not using inheritance" do
|
14
|
+
|
15
|
+
context "when passing splat args" do
|
16
|
+
|
17
|
+
let(:criteria) do
|
18
|
+
Band.only(:_id)
|
19
|
+
end
|
20
|
+
|
21
|
+
it "limits the returned fields" do
|
22
|
+
criteria.first.name.should be_nil
|
23
|
+
end
|
24
|
+
|
25
|
+
it "does not add _type to the fields" do
|
26
|
+
criteria.options[:fields]["_type"].should be_nil
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
context "when not including id" do
|
31
|
+
|
32
|
+
let(:criteria) do
|
33
|
+
Band.only(:name)
|
34
|
+
end
|
35
|
+
|
36
|
+
it "responds to id anyway" do
|
37
|
+
expect {
|
38
|
+
criteria.first.id
|
39
|
+
}.to_not raise_error
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
context "when passing an array" do
|
44
|
+
|
45
|
+
let(:criteria) do
|
46
|
+
Band.only([ :name, :likes ])
|
47
|
+
end
|
48
|
+
|
49
|
+
it "includes the limited fields" do
|
50
|
+
criteria.first.name.should_not be_nil
|
51
|
+
end
|
52
|
+
|
53
|
+
it "excludes the non included fields" do
|
54
|
+
criteria.first.active.should be_nil
|
55
|
+
end
|
56
|
+
|
57
|
+
it "does not add _type to the fields" do
|
58
|
+
criteria.options[:fields]["_type"].should be_nil
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
context "when instantiating a class of another type inside the iteration" do
|
63
|
+
|
64
|
+
let(:criteria) do
|
65
|
+
Band.only(:name)
|
66
|
+
end
|
67
|
+
|
68
|
+
it "only limits the fields on the correct model" do
|
69
|
+
criteria.each do |band|
|
70
|
+
Person.new.age.should eq(100)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
context "when instantiating a document not in the result set" do
|
76
|
+
|
77
|
+
let(:criteria) do
|
78
|
+
Band.only(:name)
|
79
|
+
end
|
80
|
+
|
81
|
+
it "only limits the fields on the correct criteria" do
|
82
|
+
criteria.each do |band|
|
83
|
+
Band.new.active.should be_true
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
context "when nesting a criteria within a criteria" do
|
89
|
+
|
90
|
+
let(:criteria) do
|
91
|
+
Band.only(:name)
|
92
|
+
end
|
93
|
+
|
94
|
+
it "only limits the fields on the correct criteria" do
|
95
|
+
criteria.each do |band|
|
96
|
+
Band.all.each do |b|
|
97
|
+
b.active.should be_true
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
context "when using inheritance" do
|
105
|
+
|
106
|
+
let(:criteria) do
|
107
|
+
Doctor.only(:_id)
|
108
|
+
end
|
109
|
+
|
110
|
+
it "adds _type to the fields" do
|
111
|
+
criteria.options[:fields]["_type"].should eq(1)
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
context "when limiting to embedded documents" do
|
116
|
+
|
117
|
+
context "when the embedded documents are aliased" do
|
118
|
+
|
119
|
+
let(:criteria) do
|
120
|
+
Person.only(:phones)
|
121
|
+
end
|
122
|
+
|
123
|
+
it "properly uses the database field name" do
|
124
|
+
criteria.options.should eq(fields: { "mobile_phones" => 1 })
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
context 'when the field is localized' do
|
130
|
+
|
131
|
+
before do
|
132
|
+
I18n.locale = :en
|
133
|
+
d = Dictionary.create(description: 'english-text')
|
134
|
+
I18n.locale = :de
|
135
|
+
d.description = 'deutsch-text'
|
136
|
+
d.save
|
137
|
+
end
|
138
|
+
|
139
|
+
after do
|
140
|
+
I18n.locale = :en
|
141
|
+
end
|
142
|
+
|
143
|
+
context 'when entire field is included' do
|
144
|
+
|
145
|
+
let(:dictionary) do
|
146
|
+
Dictionary.only(:description).first
|
147
|
+
end
|
148
|
+
|
149
|
+
it 'loads all translations' do
|
150
|
+
expect(dictionary.description_translations.keys).to include('de', 'en')
|
151
|
+
end
|
152
|
+
|
153
|
+
it 'returns the field value for the current locale' do
|
154
|
+
I18n.locale = :en
|
155
|
+
expect(dictionary.description).to eq('english-text')
|
156
|
+
I18n.locale = :de
|
157
|
+
expect(dictionary.description).to eq('deutsch-text')
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
161
|
+
context 'when a specific locale is included' do
|
162
|
+
|
163
|
+
let(:dictionary) do
|
164
|
+
Dictionary.only(:'description.de').first
|
165
|
+
end
|
166
|
+
|
167
|
+
it 'loads translations only for the included locale' do
|
168
|
+
expect(dictionary.description_translations.keys).to include('de')
|
169
|
+
expect(dictionary.description_translations.keys).to_not include('en')
|
170
|
+
end
|
171
|
+
|
172
|
+
it 'returns the field value for the included locale' do
|
173
|
+
I18n.locale = :en
|
174
|
+
expect(dictionary.description).to be_nil
|
175
|
+
I18n.locale = :de
|
176
|
+
expect(dictionary.description).to eq('deutsch-text')
|
177
|
+
end
|
178
|
+
end
|
179
|
+
|
180
|
+
context 'when entire field is excluded' do
|
181
|
+
|
182
|
+
let(:dictionary) do
|
183
|
+
Dictionary.without(:description).first
|
184
|
+
end
|
185
|
+
|
186
|
+
it 'does not load all translations' do
|
187
|
+
expect(dictionary.description_translations.keys).to_not include('de', 'en')
|
188
|
+
end
|
189
|
+
|
190
|
+
it 'raises an ActiveModel::MissingAttributeError when attempting to access the field' do
|
191
|
+
expect{dictionary.description}.to raise_error ActiveModel::MissingAttributeError
|
192
|
+
end
|
193
|
+
end
|
194
|
+
|
195
|
+
context 'when a specific locale is excluded' do
|
196
|
+
|
197
|
+
let(:dictionary) do
|
198
|
+
Dictionary.without(:'description.de').first
|
199
|
+
end
|
200
|
+
|
201
|
+
it 'does not load excluded translations' do
|
202
|
+
expect(dictionary.description_translations.keys).to_not include('de')
|
203
|
+
expect(dictionary.description_translations.keys).to include('en')
|
204
|
+
end
|
205
|
+
|
206
|
+
it 'returns nil for excluded translations' do
|
207
|
+
I18n.locale = :en
|
208
|
+
expect(dictionary.description).to eq('english-text')
|
209
|
+
I18n.locale = :de
|
210
|
+
expect(dictionary.description).to be_nil
|
211
|
+
end
|
212
|
+
end
|
213
|
+
end
|
214
|
+
end
|
215
|
+
|
216
|
+
describe "#pluck" do
|
217
|
+
|
218
|
+
let!(:depeche) do
|
219
|
+
Band.create(name: "Depeche Mode", likes: 3)
|
220
|
+
end
|
221
|
+
|
222
|
+
let!(:tool) do
|
223
|
+
Band.create(name: "Tool", likes: 3)
|
224
|
+
end
|
225
|
+
|
226
|
+
let!(:photek) do
|
227
|
+
Band.create(name: "Photek", likes: 1)
|
228
|
+
end
|
229
|
+
|
230
|
+
context "when the criteria matches" do
|
231
|
+
|
232
|
+
context "when there are no duplicate values" do
|
233
|
+
|
234
|
+
let(:criteria) do
|
235
|
+
Band.where(:name.exists => true)
|
236
|
+
end
|
237
|
+
|
238
|
+
let!(:plucked) do
|
239
|
+
criteria.pluck(:name)
|
240
|
+
end
|
241
|
+
|
242
|
+
it "returns the values" do
|
243
|
+
plucked.should eq([ "Depeche Mode", "Tool", "Photek" ])
|
244
|
+
end
|
245
|
+
|
246
|
+
context "when subsequently executing the criteria without a pluck" do
|
247
|
+
|
248
|
+
it "does not limit the fields" do
|
249
|
+
expect(criteria.first.likes).to eq(3)
|
250
|
+
end
|
251
|
+
end
|
252
|
+
end
|
253
|
+
|
254
|
+
context "when there are duplicate values" do
|
255
|
+
|
256
|
+
let(:plucked) do
|
257
|
+
Band.where(:name.exists => true).pluck(:likes)
|
258
|
+
end
|
259
|
+
|
260
|
+
it "returns the duplicates" do
|
261
|
+
plucked.should eq([ 3, 3, 1 ])
|
262
|
+
end
|
263
|
+
end
|
264
|
+
end
|
265
|
+
|
266
|
+
context "when the criteria does not match" do
|
267
|
+
|
268
|
+
let(:plucked) do
|
269
|
+
Band.where(name: "New Order").pluck(:_id)
|
270
|
+
end
|
271
|
+
|
272
|
+
it "returns an empty array" do
|
273
|
+
plucked.should be_empty
|
274
|
+
end
|
275
|
+
end
|
276
|
+
|
277
|
+
context "when plucking an aliased field" do
|
278
|
+
|
279
|
+
let(:plucked) do
|
280
|
+
Band.all.pluck(:id)
|
281
|
+
end
|
282
|
+
|
283
|
+
it "returns the field values" do
|
284
|
+
plucked.should eq([ depeche.id, tool.id, photek.id ])
|
285
|
+
end
|
286
|
+
end
|
287
|
+
|
288
|
+
context 'when plucking a localized field' do
|
289
|
+
|
290
|
+
before do
|
291
|
+
I18n.locale = :en
|
292
|
+
d = Dictionary.create(description: 'english-text')
|
293
|
+
I18n.locale = :de
|
294
|
+
d.description = 'deutsch-text'
|
295
|
+
d.save
|
296
|
+
end
|
297
|
+
|
298
|
+
after do
|
299
|
+
I18n.locale = :en
|
300
|
+
end
|
301
|
+
|
302
|
+
context 'when plucking the entire field' do
|
303
|
+
|
304
|
+
let(:plucked) do
|
305
|
+
Dictionary.all.pluck(:description)
|
306
|
+
end
|
307
|
+
|
308
|
+
it 'returns all translations' do
|
309
|
+
expect(plucked.first).to eq({'en' => 'english-text', 'de' => 'deutsch-text'})
|
310
|
+
end
|
311
|
+
end
|
312
|
+
|
313
|
+
context 'when plucking a specific locale' do
|
314
|
+
|
315
|
+
let(:plucked) do
|
316
|
+
Dictionary.all.pluck(:'description.de')
|
317
|
+
end
|
318
|
+
|
319
|
+
it 'returns the specific translations' do
|
320
|
+
expect(plucked.first).to eq({'de' => 'deutsch-text'})
|
321
|
+
end
|
322
|
+
end
|
323
|
+
end
|
324
|
+
end
|
325
|
+
end
|
326
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mongoid_monkey
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- johnnyshields
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2017-01-23 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|
@@ -67,6 +67,7 @@ files:
|
|
67
67
|
- lib/patches/big_decimal.rb
|
68
68
|
- lib/patches/db_commands.rb
|
69
69
|
- lib/patches/instrument.rb
|
70
|
+
- lib/patches/only_pluck_localized.rb
|
70
71
|
- lib/patches/reorder.rb
|
71
72
|
- lib/version.rb
|
72
73
|
- spec/app/models/account.rb
|
@@ -110,6 +111,7 @@ files:
|
|
110
111
|
- spec/unit/db_commands/moped_database_spec.rb
|
111
112
|
- spec/unit/db_commands/moped_indexes_spec.rb
|
112
113
|
- spec/unit/instrument_spec.rb
|
114
|
+
- spec/unit/only_pluck_localized.rb
|
113
115
|
- spec/unit/reorder_spec.rb
|
114
116
|
homepage: https://github.com/johnnyshields/mongoid_monkey
|
115
117
|
licenses:
|
@@ -131,7 +133,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
131
133
|
version: '0'
|
132
134
|
requirements: []
|
133
135
|
rubyforge_project:
|
134
|
-
rubygems_version: 2.
|
136
|
+
rubygems_version: 2.6.7
|
135
137
|
signing_key:
|
136
138
|
specification_version: 4
|
137
139
|
summary: Monkey patches for Mongoid
|
@@ -177,5 +179,5 @@ test_files:
|
|
177
179
|
- spec/unit/db_commands/moped_database_spec.rb
|
178
180
|
- spec/unit/db_commands/moped_indexes_spec.rb
|
179
181
|
- spec/unit/instrument_spec.rb
|
182
|
+
- spec/unit/only_pluck_localized.rb
|
180
183
|
- spec/unit/reorder_spec.rb
|
181
|
-
has_rdoc:
|