Skip to content

Commit 2e4c35b

Browse files
authored
Merge pull request #543 from rom-rb/schema_raise_multiple_names
Make Schema#[] raise when attribute name is not unique [changelog] version: unreleased changed: "`Schema#[]` and `Relation#[]` now raise an error if a given attribute is not unique (issue #529 fixed via #543) (@waiting-for-dev)"
2 parents 582e5fa + 699a9bb commit 2e4c35b

File tree

2 files changed

+17
-16
lines changed

2 files changed

+17
-16
lines changed

lib/rom/schema.rb

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -221,17 +221,16 @@ def to_h
221221
# @raise KeyError
222222
#
223223
# @api public
224-
def [](key, src = name.to_sym)
225-
attr =
226-
if count_index[key].equal?(1)
227-
name_index[key]
228-
else
229-
source_index[src][key]
230-
end
231-
232-
raise(KeyError, "#{key.inspect} attribute doesn't exist in #{src} schema") unless attr
233-
234-
attr
224+
def [](key, src = nil)
225+
if count_index[key].zero?
226+
raise(KeyError, "#{key.inspect} attribute doesn't exist in #{src} schema")
227+
elsif count_index[key] > 1 && src.nil?
228+
raise(KeyError, "#{key.inspect} attribute is not unique") if count_index[key] > 1
229+
elsif src
230+
source_index[src][key]
231+
else
232+
name_index[key]
233+
end
235234
end
236235

237236
# Project a schema to include only specified attributes
@@ -460,7 +459,9 @@ def set!(key, value)
460459

461460
# @api private
462461
def count_index
463-
map(&:name).map { |name| [name, count { |attr| attr.name == name }] }.to_h
462+
reduce(Hash.new(0)) do |index, attr|
463+
index.merge(attr.name => index[attr.name] + 1)
464+
end
464465
end
465466

466467
# @api private

spec/unit/rom/schema/accessing_attributes_spec.rb

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,10 +36,6 @@
3636
define_schema(:tasks, id: :Integer, title: :String)
3737
end
3838

39-
it "returns an attribute identified by its canonical name" do
40-
expect(schema[:id]).to eql(define_attribute(:Integer, {name: :id}, source: :users))
41-
end
42-
4339
it "returns an attribute identified by its canonical name when its unique" do
4440
expect(schema[:title]).to eql(define_attribute(:String, {name: :title}, source: :tasks))
4541
end
@@ -52,5 +48,9 @@
5248
expect { schema[:not_here] }.to raise_error(KeyError, /not_here/)
5349
expect { schema[:not_here, :tasks] }.to raise_error(KeyError, /not_here/)
5450
end
51+
52+
it "raises KeyError when attribute name is not unique" do
53+
expect { schema[:id] }.to raise_error(KeyError, /id/)
54+
end
5555
end
5656
end

0 commit comments

Comments
 (0)