Skip to content

Commit 5fa841a

Browse files
authored
MONGOID-4823 Values for BSON::Binary fields are not converted to Binary (#5317)
* MONGOID-4823 add (de)mongoize for Binary * MONGOID-4823 add tests for ObjectId * MONGOID-4823 add release note * MONGOID-4823 fix comment * MONGOID-4823 answer comments * MONGOID-4823 use ::BSON * Revert "MONGOID-4823 use ::BSON" This reverts commit 5c893e9. * MONGOID-4823 revert back to without ::BSON * MONGOID-4823 fix document test
1 parent c50a4fd commit 5fa841a

File tree

6 files changed

+275
-4
lines changed

6 files changed

+275
-4
lines changed

docs/release-notes/mongoid-8.0.txt

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -447,3 +447,28 @@ For example:
447447

448448
As you can see from this example, after pushing ``user2`` to the users array,
449449
Mongoid 8 correctly updates the number of elements without requiring a reload.
450+
451+
452+
Repaired Storing Strings in BSON::Binary fields
453+
-----------------------------------------------
454+
455+
In Mongoid 8, storing a String in a field of type ``BSON::Binary`` will be
456+
stored in and returned from the database as a ``BSON::Binary``. Prior to Mongoid 8
457+
it was stored and returned as a String.
458+
459+
.. code::
460+
461+
class Registry
462+
include Mongoid::Document
463+
field :data, type: BSON::Binary
464+
end
465+
466+
registry = Registry.create!(data: "data!")
467+
p registry.data
468+
# => Mongoid 7: "data!"
469+
# => Mongoid 8: <BSON::Binary:0x2580 type=generic data=0x6461746121...>
470+
471+
registry = Registry.find(registry.id)
472+
p registry.data
473+
# => Mongoid 7: "data!"
474+
# => Mongoid 8: <BSON::Binary:0x2600 type=generic data=0x6461746121...>

lib/mongoid/extensions.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ def transform_keys
3434

3535
require "mongoid/extensions/array"
3636
require "mongoid/extensions/big_decimal"
37+
require "mongoid/extensions/binary"
3738
require "mongoid/extensions/boolean"
3839
require "mongoid/extensions/date"
3940
require "mongoid/extensions/date_time"

lib/mongoid/extensions/binary.rb

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
# frozen_string_literal: true
2+
3+
module Mongoid
4+
module Extensions
5+
module Binary
6+
7+
# Turn the object from the ruby type we deal with to a Mongo friendly
8+
# type.
9+
#
10+
# @example Mongoize the object.
11+
# object.mongoize
12+
#
13+
# @return [ Object ] The object.
14+
def mongoize
15+
BSON::Binary.mongoize(self)
16+
end
17+
18+
module ClassMethods
19+
20+
# Mongoize an object of any type to how it's stored in the db.
21+
#
22+
# @example Mongoize the object.
23+
# BigDecimal.mongoize(123)
24+
#
25+
# @param [ Object ] object The object to Mongoize
26+
#
27+
# @return [ String | Symbol | BSON::Binary | nil ] A String or Binary
28+
# representing the object or nil.
29+
def mongoize(object)
30+
return if object.nil?
31+
32+
case object
33+
when BSON::Binary
34+
object
35+
when String, Symbol
36+
BSON::Binary.new(object.to_s)
37+
else
38+
# TODO: MONGOID-5222 raise on the setting of feature flag.
39+
nil
40+
end
41+
end
42+
end
43+
end
44+
end
45+
end
46+
47+
BSON::Binary.__send__(:include, Mongoid::Extensions::Binary)
48+
BSON::Binary.extend(Mongoid::Extensions::Binary::ClassMethods)

spec/mongoid/document_fields_spec.rb

Lines changed: 152 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,20 +40,168 @@
4040
end
4141

4242
it 'assigns as a BSON::Binary object' do
43-
pending 'https://jira.mongodb.org/browse/MONGOID-4823'
44-
4543
registry.data.should be_a(BSON::Binary)
4644
end
4745

4846
it 'persists' do
49-
pending 'https://jira.mongodb.org/browse/MONGOID-4823'
50-
5147
registry.save!
5248

5349
_registry = Registry.find(registry.id)
5450
_registry.data.should == BSON::Binary.new(data)
5551
end
5652
end
53+
54+
context 'when assigned nil' do
55+
let(:data) do
56+
nil
57+
end
58+
59+
let(:registry) do
60+
Registry.new(data: data)
61+
end
62+
63+
it 'assigns nil' do
64+
registry.data.should be nil
65+
end
66+
67+
it 'persists' do
68+
registry.save!
69+
70+
_registry = Registry.find(registry.id)
71+
_registry.data.should be nil
72+
end
73+
end
74+
75+
# TODO: MONGOID-5222 test with uncastable feature flag
76+
context 'when assigned an invalid type' do
77+
let(:data) do
78+
true
79+
end
80+
81+
let(:registry) do
82+
Registry.new(data: data)
83+
end
84+
85+
it 'assigns nil' do
86+
registry.data.should be nil
87+
end
88+
89+
it 'persists' do
90+
registry.save!
91+
92+
_registry = Registry.find(registry.id)
93+
_registry.data.should be nil
94+
end
95+
end
96+
end
97+
98+
describe 'BSON::ObjectId field' do
99+
context 'when assigned a BSON::ObjectId instance' do
100+
let(:obj_id) do
101+
BSON::ObjectId.new
102+
end
103+
104+
let(:registry) do
105+
Registry.new(obj_id: obj_id)
106+
end
107+
108+
it 'does not freeze the specified data' do
109+
registry
110+
111+
obj_id.should_not be_frozen
112+
end
113+
114+
it 'persists' do
115+
registry.save!
116+
117+
_registry = Registry.find(registry.id)
118+
_registry.obj_id.should == obj_id
119+
end
120+
end
121+
122+
context 'when assigned a valid string' do
123+
let(:obj_id) do
124+
BSON::ObjectId.new.to_s
125+
end
126+
127+
let(:registry) do
128+
Registry.new(obj_id: obj_id)
129+
end
130+
131+
it 'assigns as a BSON::Binary object' do
132+
registry.obj_id.should be_a(BSON::ObjectId)
133+
end
134+
135+
it 'persists' do
136+
registry.save!
137+
138+
_registry = Registry.find(registry.id)
139+
_registry.obj_id.should == BSON::ObjectId.from_string(obj_id)
140+
end
141+
end
142+
143+
context 'when assigned nil' do
144+
let(:obj_id) do
145+
nil
146+
end
147+
148+
let(:registry) do
149+
Registry.new(obj_id: obj_id)
150+
end
151+
152+
it 'assigns nil' do
153+
registry.obj_id.should be nil
154+
end
155+
156+
it 'persists' do
157+
registry.save!
158+
159+
_registry = Registry.find(registry.id)
160+
_registry.obj_id.should be nil
161+
end
162+
end
163+
164+
context 'when assigned an invalid string' do
165+
let(:obj_id) do
166+
"hello"
167+
end
168+
169+
let(:registry) do
170+
Registry.new(obj_id: obj_id)
171+
end
172+
173+
it 'assigns nil' do
174+
registry.obj_id.should == "hello"
175+
end
176+
177+
it 'persists' do
178+
registry.save!
179+
180+
_registry = Registry.find(registry.id)
181+
_registry.obj_id.should == "hello"
182+
end
183+
end
184+
185+
context 'when assigned an invalid type' do
186+
let(:obj_id) do
187+
:sym
188+
end
189+
190+
let(:registry) do
191+
Registry.new(obj_id: obj_id)
192+
end
193+
194+
it 'assigns nil' do
195+
registry.obj_id.should == :sym
196+
end
197+
198+
it 'persists' do
199+
registry.save!
200+
201+
_registry = Registry.find(registry.id)
202+
_registry.obj_id.should == :sym
203+
end
204+
end
57205
end
58206

59207
describe 'Hash field' do

spec/mongoid/extensions/binary_spec.rb

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,54 @@
1515
end
1616
end
1717

18+
describe ".mongoize" do
19+
20+
let(:binary) do
21+
BSON::Binary.new("testing")
22+
end
23+
24+
let(:mongoized) do
25+
BSON::Binary.mongoize(value)
26+
end
27+
28+
context "when mongoizing a BSON::Binary" do
29+
30+
let(:value) { binary }
31+
32+
it "returns the binary" do
33+
expect(mongoized).to eq(binary)
34+
end
35+
end
36+
37+
context "when mongoizing a String" do
38+
39+
let(:value) { "testing" }
40+
41+
it "returns it as binary" do
42+
expect(mongoized).to eq(binary)
43+
end
44+
end
45+
46+
context "when mongoizing nil" do
47+
48+
let(:value) { nil }
49+
50+
it "returns nil" do
51+
expect(mongoized).to eq(nil)
52+
end
53+
end
54+
55+
context "when mongoizing an invalid type" do
56+
57+
let(:value) { true }
58+
59+
# TODO: MONGOID-5222 test with feature flag on and off
60+
it "returns nil" do
61+
expect(mongoized).to eq(nil)
62+
end
63+
end
64+
end
65+
1866
describe ".demongoize" do
1967

2068
let(:binary) do

spec/support/models/registry.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,5 @@
33
class Registry
44
include Mongoid::Document
55
field :data, type: BSON::Binary
6+
field :obj_id, type: BSON::ObjectId
67
end

0 commit comments

Comments
 (0)