Today I Learned

A JetRockets project

1 post by Alexander Spitsyn

How to implement inheritance in Grape resources?

Grape uses specific DSL to define endpoints in API, that’s why you can’t use base class’ instance methods in descendant resources. But there’s one trick:

There’s an #inherited class method in Ruby which is triggered every time some class inherits from ancestor class. It passes one argument - descendant class. Calling descendant’s #instance_eval method we can place any useful stuff inside a block: methods, helpers, before-do’s, etc, in this way evaluating it in context of subclass.

class Base < Grape::API
  def self.inherited(subclass)
    super

    subclass.instance_eval do
      helpers do
        def current_user
          @current_user ||= User.find(params[:user_id])
        end
      end
      # ...
    end 
  end
end

class DocumentsResource < Base
  post '/documents' do
    @document = current_user.documents.build
    # ...
  end
end

Note that it’s not real inheritance because Base class has not methods defined inside subclass#instance_eval block.