Skip to content

Commit 4452804

Browse files
neilshwekyp
andcommitted
RUBY-2857 Reorder DBRef fields to have $ref/$id/$db first (#261)
* Revert "from_bson override is no longer needed" This reverts commit cf2d99b. * RUBY-2857 Reorder DBRef fields to have $ref/$id/$db first * RUBY-2857 handle dup and symbol cases * RUBY-2857 move the instantiation of bson document * get rid of from_bson again * RUBY-2857 remove argument from super Co-authored-by: Oleg Pudeyev <[email protected]>
1 parent 988a303 commit 4452804

File tree

2 files changed

+88
-2
lines changed

2 files changed

+88
-2
lines changed

lib/bson/dbref.rb

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,8 +66,9 @@ def as_json(*args)
6666
# @example Create the DBRef.
6767
# BSON::DBRef.new({'$ref' => 'users', '$id' => id, '$db' => 'database'})
6868
#
69-
# @param [ Hash ] hash the DBRef hash. It must contain $collection and $id.
69+
# @param [ Hash ] hash the DBRef hash. It must contain $ref and $id.
7070
def initialize(hash)
71+
hash = reorder_fields(hash)
7172
%w($ref $id).each do |key|
7273
unless hash[key]
7374
raise ArgumentError, "DBRef must have #{key}: #{hash}"
@@ -84,7 +85,7 @@ def initialize(hash)
8485
end
8586
end
8687

87-
super(hash)
88+
super
8889
end
8990

9091
# Converts the DBRef to raw BSON.
@@ -99,5 +100,26 @@ def initialize(hash)
99100
def to_bson(buffer = ByteBuffer.new, validating_keys = Config.validating_keys?)
100101
as_json.to_bson(buffer, validating_keys)
101102
end
103+
104+
private
105+
106+
# Reorder the fields of the given Hash to have $ref first, $id second,
107+
# and $db third. The rest of the fields in the hash can come in any
108+
# order after that.
109+
#
110+
# @param [ Hash ] hash The input hash. Must be a valid dbref.
111+
#
112+
# @return [ Hash ] The hash with it's fields reordered.
113+
def reorder_fields(hash)
114+
hash = BSON::Document.new(hash)
115+
reordered = {}
116+
reordered['$ref'] = hash.delete('$ref')
117+
reordered['$id'] = hash.delete('$id')
118+
if db = hash.delete('$db')
119+
reordered['$db'] = db
120+
end
121+
122+
reordered.update(hash)
123+
end
102124
end
103125
end

spec/bson/dbref_spec.rb

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,70 @@
131131
end.to raise_error(ArgumentError, /The value for key \$db must be a string/)
132132
end
133133
end
134+
135+
context 'when providing the fieds as symbols' do
136+
let(:hash) do
137+
{ :$ref => 'users', :$id => object_id, :$db => 'db' }
138+
end
139+
140+
it 'does not raise an error' do
141+
expect do
142+
dbref
143+
end.to_not raise_error
144+
end
145+
end
146+
147+
context 'when testing the ordering of the fields' do
148+
context 'when the fields are in order' do
149+
let(:hash) do
150+
{ '$ref' => 'users', '$id' => object_id, '$db' => 'db' }
151+
end
152+
153+
it 'has the correct order' do
154+
expect(dbref.keys).to eq(['$ref', '$id', '$db'])
155+
end
156+
end
157+
158+
context 'when the fields are out of order' do
159+
let(:hash) do
160+
{ '$db' => 'db', '$id' => object_id, '$ref' => 'users' }
161+
end
162+
163+
it 'has the correct order' do
164+
expect(dbref.keys).to eq(['$ref', '$id', '$db'])
165+
end
166+
end
167+
168+
context 'when there is no db' do
169+
let(:hash) do
170+
{ '$id' => object_id, '$ref' => 'users' }
171+
end
172+
173+
it 'has the correct order' do
174+
expect(dbref.keys).to eq(['$ref', '$id'])
175+
end
176+
end
177+
178+
context 'when the there are other fields in order' do
179+
let(:hash) do
180+
{ '$ref' => 'users', '$id' => object_id, '$db' => 'db', 'x' => 'y', 'y' => 'z' }
181+
end
182+
183+
it 'has the correct order' do
184+
expect(dbref.keys).to eq(['$ref', '$id', '$db', 'x', 'y'])
185+
end
186+
end
187+
188+
context 'when the there are other fields out of order' do
189+
let(:hash) do
190+
{ 'y' => 'z', '$db' => 'db', '$id' => object_id, 'x' => 'y', '$ref' => 'users' }
191+
end
192+
193+
it 'has the correct order' do
194+
expect(dbref.keys).to eq(['$ref', '$id', '$db', 'y', 'x'])
195+
end
196+
end
197+
end
134198
end
135199

136200
describe '#to_bson' do

0 commit comments

Comments
 (0)