diff --git a/core/lib/rom/schema.rb b/core/lib/rom/schema.rb index 3777c60a2..afd926fa1 100644 --- a/core/lib/rom/schema.rb +++ b/core/lib/rom/schema.rb @@ -220,19 +220,16 @@ def to_h # @raise KeyError # # @api public - def [](key, src = name.to_sym) - attr = - if count_index[key].equal?(1) - name_index[key] - else - source_index[src][key] - end - - unless attr + def [](key, src = nil) + if count_index[key] == 0 raise(KeyError, "#{key.inspect} attribute doesn't exist in #{src} schema") + elsif count_index[key] > 1 && src.nil? + raise(KeyError, "#{key.inspect} attribute is not unique") if count_index[key] > 1 + elsif src + source_index[src][key] + else + name_index[key] end - - attr end # Project a schema to include only specified attributes @@ -460,7 +457,9 @@ def set!(key, value) # @api private def count_index - map(&:name).map { |name| [name, count { |attr| attr.name == name }] }.to_h + reduce(Hash.new(0)) do |index, attr| + index.merge(attr.name => index[attr.name] + 1) + end end # @api private diff --git a/core/spec/unit/rom/schema/accessing_attributes_spec.rb b/core/spec/unit/rom/schema/accessing_attributes_spec.rb index 1e44a1df2..f4dfd150b 100644 --- a/core/spec/unit/rom/schema/accessing_attributes_spec.rb +++ b/core/spec/unit/rom/schema/accessing_attributes_spec.rb @@ -34,10 +34,6 @@ define_schema(:tasks, id: :Integer, title: :String) end - it 'returns an attribute identified by its canonical name' do - expect(schema[:id]).to eql(define_attribute(:Integer, { name: :id }, source: :users)) - end - it 'returns an attribute identified by its canonical name when its unique' do expect(schema[:title]).to eql(define_attribute(:String, { name: :title }, source: :tasks)) end @@ -50,5 +46,9 @@ expect { schema[:not_here] }.to raise_error(KeyError, /not_here/) expect { schema[:not_here, :tasks] }.to raise_error(KeyError, /not_here/) end + + it 'raises KeyError when attribute name is not unique' do + expect { schema[:id] }.to raise_error(KeyError, /id/) + end end end