diff --git a/CHANGELOG.md b/CHANGELOG.md index 84c4e024..abca27f3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ Next Release ============ * Your contribution here. +* [#110](https://github.com/intridea/grape-entity/pull/110): Fixed safe exposure when using `Hash` models - [@croeck](https://github.com/croeck). * [#109](https://github.com/intridea/grape-entity/pull/109): Add unexpose method - [@jonmchan](https://github.com/jonmchan). * [#98](https://github.com/intridea/grape-entity/pull/98): Add nested conditionals - [@zbelzer](https://github.com/zbelzer). * [#91](https://github.com/intridea/grape-entity/pull/91): Fix OpenStruct serializing - [@etehtsea](https://github.com/etehtsea). diff --git a/lib/grape_entity/entity.rb b/lib/grape_entity/entity.rb index 7261c2cc..36fe6687 100644 --- a/lib/grape_entity/entity.rb +++ b/lib/grape_entity/entity.rb @@ -576,7 +576,8 @@ def valid_exposure?(attribute, exposure_options) (nested_exposures.any? && nested_exposures.all? { |a, o| valid_exposure?(a, o) }) || \ exposure_options.key?(:proc) || \ !exposure_options[:safe] || \ - object.respond_to?(self.class.name_for(attribute)) + object.respond_to?(self.class.name_for(attribute)) || \ + object.is_a?(Hash) && object.key?(self.class.name_for(attribute)) end def conditions_met?(exposure_options, options) diff --git a/spec/grape_entity/entity_spec.rb b/spec/grape_entity/entity_spec.rb index 26b28c86..ce74321f 100644 --- a/spec/grape_entity/entity_spec.rb +++ b/spec/grape_entity/entity_spec.rb @@ -683,6 +683,13 @@ class Parent < Person expect(res).to have_key :name end + it 'does expose attributes marked as safe if model is a hash object' do + fresh_class.expose :name, safe: true + + res = fresh_class.new(name: 'myname').serializable_hash + expect(res).to have_key :name + end + it "does not expose attributes that don't exist on the object, even with criteria" do fresh_class.expose :email fresh_class.expose :nonexistent_attribute, safe: true, if: lambda { false }