mongoid_monkey 0.1.4 → 0.2.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: 214e7694779c183b25d31b4a3acd022b6d197883
4
- data.tar.gz: ba65a452be5ef5778673fb790872ad7e879e368e
3
+ metadata.gz: 118a2a99faa547a7a3336586d933db15563d8069
4
+ data.tar.gz: 97f311b750030497fd6c1a63da61d369bbcfbdb1
5
5
  SHA512:
6
- metadata.gz: 9c3906fb7a21840e4e1688bc1f9f9bcbfa608d3083533d52b87cb8caf31783dfe6aea1ae462b85c6908cb9d9b05ec35cd5e04e6d83e2e0750dbcb2f231d96c1b
7
- data.tar.gz: 9c0dc36cb5537f059791b16d43ba2dd5fb3337d3597e3dfc4600c469d3717166a6761a5d8a335731dae3e6810340aad0e7a1b51bea69136af6a78bbab17d1864
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
 
@@ -5,3 +5,4 @@ require 'patches/big_decimal'
5
5
  require 'patches/db_commands'
6
6
  require 'patches/instrument'
7
7
  require 'patches/reorder'
8
+ require 'patches/only_pluck_localized'
@@ -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
@@ -1,3 +1,3 @@
1
1
  module MongoidMonkey
2
- VERSION = '0.1.4'
2
+ VERSION = '0.2.0'
3
3
  end
@@ -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.1.4
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: 2016-03-11 00:00:00.000000000 Z
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.4.7
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: