Skip to content

Commit 790a5ce

Browse files
MONGOID-5390: Mongoid::Contextual::Memory#pluck should return nil values (#5331)
* MONGOID-5390: Mongoid::Contextual::Memory#pluck should return nil values. Conveniently, we can now use ActiveSupport's Array#pluck here, introduced in Rails 5.0. * Array.wrap not needed * Docs * Add release notes * Update mongoid-8.0.txt * Update mongoid-8.0.txt * Comment fix * Update docs/release-notes/mongoid-8.0.txt Co-authored-by: Oleg Pudeyev <[email protected]> * Update mongoid-8.0.txt * Update mongoid-8.0.txt * More fixes to readme * Change splat in doc * Make "when plucking a mix of empty and non-empty values" its own spec Co-authored-by: shields <[email protected]> Co-authored-by: Oleg Pudeyev <[email protected]>
1 parent 56a6f6a commit 790a5ce

File tree

3 files changed

+87
-10
lines changed

3 files changed

+87
-10
lines changed

docs/release-notes/mongoid-8.0.txt

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -304,6 +304,61 @@ Mongoid 7 behavior:
304304
end
305305

306306

307+
``#pluck`` on Embedded Criteria Returns ``nil`` Values
308+
------------------------------------------------
309+
310+
Mongoid 8 fixes a bug where calling ``#pluck`` on a Mongoid::Criteria
311+
for embedded documents discarded nil values. This behavior was
312+
inconsistent with both the ``#pluck`` method in ActiveSupport and
313+
with how ``#pluck`` works when reading documents from the database.
314+
315+
Mongoid 8.0 behavior:
316+
317+
.. code-block:: ruby
318+
319+
class Address
320+
include Mongoid::Document
321+
322+
embedded_in :mall
323+
324+
field :street, type: String
325+
end
326+
327+
class Mall
328+
include Mongoid::Document
329+
330+
embeds_many :addresses
331+
end
332+
333+
mall = Mall.create!
334+
mall.addresses.create!(street: "Elm Street")
335+
mall.addresses.create!(street: nil)
336+
337+
# Pluck from embedded document criteria
338+
mall.addresses.all.pluck(:street)
339+
#=> ['Elm Street', nil]
340+
341+
Mongoid 7 behavior, given the same setup:
342+
343+
.. code-block:: ruby
344+
345+
# Pluck from embedded document criteria
346+
mall.addresses.all.pluck(:street)
347+
#=> ['Elm Street']
348+
349+
For clarity, the following behavior is unchanged from Mongoid 7 to Mongoid 8.0:
350+
351+
.. code-block:: ruby
352+
353+
# Pluck from database
354+
Mall.all.pluck('addresses.street')
355+
#=> [ ['Elm Street', nil] ]
356+
357+
# Pluck using ActiveSupport Array#pluck
358+
mall.addresses.pluck(:street)
359+
#=> ['Elm Street', nil]
360+
361+
307362
Removed ``:drop_dups`` Option from Indexes
308363
------------------------------------------
309364

lib/mongoid/contextual/memory.rb

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -188,15 +188,16 @@ def limit(value)
188188
self
189189
end
190190

191+
# Pluck the field values in memory.
192+
#
193+
# @example Get the values in memory.
194+
# context.pluck(:name)
195+
#
196+
# @param [ String | Symbol ] *fields Field(s) to pluck.
197+
#
198+
# @return [ Array ] The array of plucked values.
191199
def pluck(*fields)
192-
fields = Array.wrap(fields)
193-
documents.map do |doc|
194-
if fields.size == 1
195-
doc[fields.first]
196-
else
197-
fields.map { |n| doc[n] }.compact
198-
end
199-
end.compact
200+
documents.pluck(*fields)
200201
end
201202

202203
# Skips the provided number of documents.

spec/mongoid/contextual/memory_spec.rb

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -948,6 +948,27 @@
948948
end
949949
end
950950

951+
context "when plucking a mix of empty and non-empty values" do
952+
953+
let(:empty_doc) do
954+
Address.new(street: nil)
955+
end
956+
957+
let(:criteria) do
958+
Address.all.tap do |crit|
959+
crit.documents = [ hobrecht, friedel, empty_doc ]
960+
end
961+
end
962+
963+
let!(:plucked) do
964+
context.pluck(:street)
965+
end
966+
967+
it "returns the values" do
968+
expect(plucked).to eq([ "hobrecht", "friedel", nil ])
969+
end
970+
end
971+
951972
context "when plucking a field that doesnt exist" do
952973

953974
context "when pluck one field" do
@@ -957,7 +978,7 @@
957978
end
958979

959980
it "returns a empty array" do
960-
expect(plucked).to eq([])
981+
expect(plucked).to eq([nil, nil])
961982
end
962983
end
963984

@@ -968,7 +989,7 @@
968989
end
969990

970991
it "returns a empty array" do
971-
expect(plucked).to eq([[], []])
992+
expect(plucked).to eq([[nil, nil], [nil, nil]])
972993
end
973994
end
974995
end

0 commit comments

Comments
 (0)