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.
Share: