Skip to content

Evaluate expose block in instance context #28

Closed
@MichaelXavier

Description

@MichaelXavier

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?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions