Skip to content

Commit

Permalink
Try method on entity before trying object
Browse files Browse the repository at this point in the history
Resolves ruby-grape#28
  • Loading branch information
MichaelXavier committed Oct 15, 2013
1 parent 409225e commit e065478
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 4 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ Next Release
* [#16](https://github.com/intridea/grape-entity/pull/16): Add `using` option to `expose SYMBOL BLOCK` - [@fahchen](https://github.com/fahchen).
* [#24](https://github.com/intridea/grape-entity/pull/24): Return documentation with `as` param considered - [@drakula2k](https://github.com/drakula2k).
* [#27](https://github.com/intridea/grape-entity/pull/27): Properly serializing hashes - [@clintonb](https://github.com/clintonb).
* [#28](https://github.com/intridea/grape-entity/pull/28): Look for method on entity before calling on the object - [@MichaelXavier](https://github.com/MichaelXavier).
* Your contribution here.

0.3.0 (2013-03-29)
Expand Down
15 changes: 15 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,21 @@ end
expose :digest, proc: ... # equivalent to a block
```

You can also define a method on the entity and it will try that before trying
on the object the entity wraps.

```
class ExampleEntity < Grape::Entity
expose :attr_not_on_wrapped_object
# ...
private
def attr_not_on_wrapped_object
42
end
end
```

#### Aliases

Expose under a different name with `:as`.
Expand Down
16 changes: 12 additions & 4 deletions lib/grape_entity/entity.rb
Original file line number Diff line number Diff line change
Expand Up @@ -390,17 +390,25 @@ def value_for(attribute, options = {})
using_options = options.dup
using_options.delete(:collection)
using_options[:root] = nil
exposure_options[:using].represent(object.send(attribute), using_options)
exposure_options[:using].represent(delegate_attribute(attribute), using_options)
elsif exposure_options[:format_with]
format_with = exposure_options[:format_with]

if format_with.is_a?(Symbol) && formatters[format_with]
formatters[format_with].call(object.send(attribute))
formatters[format_with].call(delegate_attribute(attribute))
elsif format_with.is_a?(Symbol)
self.send(format_with, object.send(attribute))
self.send(format_with, delegate_attribute(attribute))
elsif format_with.respond_to? :call
format_with.call(object.send(attribute))
format_with.call(delegate_attribute(attribute))
end
else
delegate_attribute(attribute)
end
end

def delegate_attribute(attribute)
if respond_to?(attribute, true)
send(attribute)
else
object.send(attribute)
end
Expand Down
20 changes: 20 additions & 0 deletions spec/grape_entity/entity_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -602,6 +602,26 @@ class FriendEntity < Grape::Entity
it 'returns a formatted value if format_with is passed a lambda' do
subject.send(:value_for, :fantasies).should == ['Nessy', 'Double Rainbows', 'Unicorns']
end

it "tries instance methods on the entity first" do
module EntitySpec
class DelegatingEntity < Grape::Entity
root 'friends', 'friend'
expose :name
expose :email

private
def name
"cooler name"
end
end
end

friend = double("Friend", :name => "joe", :email => "joe@example.com")
rep = EntitySpec::DelegatingEntity.new(friend)
rep.send(:value_for, :name).should == "cooler name"
rep.send(:value_for, :email).should == "joe@example.com"
end
end

describe '#documentation' do
Expand Down

0 comments on commit e065478

Please sign in to comment.