Description
I noticed that the block version of an exposure pretty much runs without any usable context. The context it currently uses is the class of the entity, which doesn't really provide much, passing in the object being wrapped and the options.
I think it would be a lot cleaner and more intuitive if the block was evaluated in the context of the instance around here.
Here's an example use case where that cleans things up:
class ProductEntity < Grape::Entity
expose :local_prices do
prices.select(&:local?)
end
expose :web_prices do
prices.select(&:web?)
end
private
def prices
@prices ||= expensive_api_call
end
end
This doesn't work currently because the prices method is on the instance but the block gets evaluated on the class. Wouldn't want to add the prices method to the class because it is stateful.
Alternatively (and I prefer this), you could have exposures see if the entity responds to it first, and if not delegate to the object as normal. I think Roar does this and it is much easier to build a proper facade that way. Admittedly, it is a more breaking API change. For comparison:
class ProductEntity < Grape::Entity
expose :local_prices
expose :web_prices
expose :attribute_on_the_product
private
def web_prices
prices.select(&:web?)
end
def local_prices
prices.select(&:local?)
end
def prices
@prices ||= expensive_api_call
end
end
Thoughts?