Skip to content

No Entity class lookup for collections #304

Description

@tscholz

Hi there!

Thanks for the great gem. I like it a lot.

I'm new to Grape, so maybe I'm missing something. When using a custom entity with present_collection true the implicit lookup for the entity class of records in the :items array does not work.

Thank you for looking into this.

# frozen_string_literal: true

begin
  require "bundler/inline"
rescue LoadError => e
  $stderr.puts "Bundler version 1.10 or later is required. Please update your Bundler"
  raise e
end

gemfile(true) do
  source 'https://rubygems.org'

  gem 'grape'
  gem 'grape-entity'

  gem 'rack-test'
  gem 'rspec'
  gem 'byebug'
end

class Item
  attr_accessor :id, :name

  def initialize(id, name)
    @id, @name = id, name
  end

  def to_json(_opts = {})
    {id: id, name: name}.to_json
  end

  def entity
    Entity.new self
  end

  class Entity < Grape::Entity
    expose :id, as: 'THE_ID'
    expose :name, as: 'THE_NAME'
  end
end

class CollectionEntity < Grape::Entity
  present_collection true, :items

  expose :meta do
    expose :current_page
    expose :next_page
  end

  # No ', using: Item::Entity' here as I'd like to use the collecion
  # entity for different types of objects. I'd expect the implicit entity
  # lookup here.
  expose :items

  def next_page
    current_page + 1
  end

  def current_page
    options.fetch :current_page
  end
end

class API < Grape::API
  version 'v1'
  format :json

  resource :items do
    desc 'Get items'
    params do
      optional :page, type: Integer, default: 1
      optional :per_page, type: Integer, default: 10
    end
    get do
      items = (1..1).to_a.map { |n| Item.new(n, "Item_#{n}") }

      present items, with: CollectionEntity, current_page: params[:page]
    end

    desc 'Get a item'
    params do
      requires :id, type: Integer
    end
    route_param :id do
      get do
        id = params[:id]
        present Item.new id, "Item_#{id}"
      end
    end
  end

end

require 'json'
require 'rspec/autorun'

describe API do
  include Rack::Test::Methods

  def app
    API
  end

  context 'get /v1/items' do

    # BROKEN TEST :(
    it 'is using Item::Entity for collection members' do
      get '/v1/items'
      expect(last_response.status).to eq(200)

      json = JSON.parse last_response.body
      item = json['items'].first

      expect(item).to eq({'THE_ID' => 1, 'THE_NAME' => 'Item_1'})
    end
  end


  context 'get /v1/items/:id' do

    it 'is using Item::Entity' do
      get '/v1/items/1'
      expect(last_response.status).to eq(200)

      item = JSON.parse last_response.body

      expect(item).to eq({'THE_ID' => 1, 'THE_NAME' => 'Item_1'})
    end
  end
end

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

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