From dbb7587d971dcb23c2d6a7b7f82d812fd929485b Mon Sep 17 00:00:00 2001 From: Adam Gotterer Date: Fri, 13 Jul 2012 16:06:59 -0400 Subject: [PATCH] Improved Entity#serializable_hash to check that an attribute exists on an object before accessing it. Improved Entity#serializable_hash check for an entity on an object before accessing the value. Converted proc and using condition to #conditions_met --- CHANGELOG.markdown | 4 ++++ lib/grape/entity.rb | 5 ++++- spec/grape/entity_spec.rb | 25 +++++++++++++++++++++++++ 3 files changed, 33 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.markdown b/CHANGELOG.markdown index 538d174d45..4c1b30902e 100644 --- a/CHANGELOG.markdown +++ b/CHANGELOG.markdown @@ -1,3 +1,7 @@ +0.2.2 +================= +* [#203](https://github.com/intridea/grape/pull/203): Added a check to Entity#serializable_hash that verifies an entity exists on an object - [@adamgotterer](https://github.com/adamgotterer). + 0.2.1 (7/11/2012) ================= diff --git a/lib/grape/entity.rb b/lib/grape/entity.rb index 890cf83849..3b013f64d2 100644 --- a/lib/grape/entity.rb +++ b/lib/grape/entity.rb @@ -259,7 +259,10 @@ def serializable_hash(runtime_options = {}) return nil if object.nil? opts = options.merge(runtime_options || {}) exposures.inject({}) do |output, (attribute, exposure_options)| - output[key_for(attribute)] = value_for(attribute, opts) if conditions_met?(exposure_options, opts) + if object.respond_to?(attribute) && conditions_met?(exposure_options, opts) + output[key_for(attribute)] = value_for(attribute, opts) + end + output end end diff --git a/spec/grape/entity_spec.rb b/spec/grape/entity_spec.rb index 305806724d..eb9b4c637b 100644 --- a/spec/grape/entity_spec.rb +++ b/spec/grape/entity_spec.rb @@ -257,6 +257,31 @@ fresh_class.expose :name expect{ fresh_class.new(nil).serializable_hash }.not_to raise_error end + + it 'should not throw an exception when an attribute is not found on the object' do + fresh_class.expose :name, :non_existant_attribute + expect{ fresh_class.new(model).serializable_hash }.not_to raise_error + end + + it "should not expose attributes that don't exist on the object" do + fresh_class.expose :email, :non_existant_attribute, :name + + res = fresh_class.new(model).serializable_hash + res.should have_key :email + res.should_not have_key :non_existant_attribute + res.should have_key :name + end + + it "should not expose attributes that don't exist on the object, even with criteria" do + fresh_class.expose :email + fresh_class.expose :non_existant_attribute, :if => lambda { false } + fresh_class.expose :non_existant_attribute2, :if => lambda { true } + + res = fresh_class.new(model).serializable_hash + res.should have_key :email + res.should_not have_key :non_existant_attribute + res.should_not have_key :non_existant_attribute2 + end end describe '#value_for' do