module Sinatra::API::Resources
API
for defining parameters an endpoint requires or accepts, their types, and optional validators.
Public Class Methods
included(app)
click to toggle source
# File lib/sinatra/api/resources.rb, line 28 def self.included(app) app.set(:requires) do |*resources| condition do @required = resources.collect { |r| r.to_s } @required.each do |r| @parent_resource = api_locate_resource(r, @parent_resource) end end end Sinatra::API.on :request do |instance| @parent_resource = nil end end
Private Instance Methods
api_locate_resource(r, container = nil)
click to toggle source
Attempt to locate a resource based on an ID supplied in a request parameter.
If the param map contains a resource id (ie, :folder_id), we attempt to locate and expose it to the route.
A 404 is raised if:
1. the scope is missing 2. the resource couldn't be found in its scope
If the resources were located, they’re accessible using @folder or @page.
The route can be halted using the :requires => [] condition when it expects a resource.
@example using :requires to reject a request with an invalid @page
get '/folders/:folder_id/pages/:page_id', :requires => [ :page ] do @page.show # page is good @folder.show # so is its folder end
# File lib/sinatra/api/resources.rb, line 67 def api_locate_resource(r, container = nil) resource_id = params[r + '_id'].to_i rklass = r.camelize collection = case when container.nil?; eval "#{ResourcePrefix}#{rklass}" else; container.send("#{r.to_plural}") end Sinatra::API.logger.debug "locating resource #{r} with id #{resource_id} " + "from #{collection} [#{container}]" resource = collection.get(resource_id) if !resource m = "No such resource: #{rklass}##{resource_id}" if container m << " in #{container.class.name.to_s}##{container.id}" end halt 404, m end if respond_to?(:can?) unless can? :access, resource halt 403, "You do not have access to this #{rklass} resource." end end instance_variable_set('@'+r, resource) Sinatra::API.trigger :resource_located, resource, r resource end