class Toast::CollectionRequest
Public Class Methods
new(config, base_config, auth, request)
click to toggle source
# File lib/toast/collection_request.rb, line 8 def initialize config, base_config, auth, request @config = config @base_config = base_config @base_uri = base_uri(request) @verb = request.request_method.downcase @requested_range = Toast::HttpRange.new(request.env['HTTP_RANGE']) @selected_attributes = request.query_parameters[:toast_select].try(:split,/ *, */) @uri_params = request.query_parameters @auth = auth @request = request end
Public Instance Methods
respond()
click to toggle source
# File lib/toast/collection_request.rb, line 20 def respond if @verb.in? %w(get post) self.send(@verb) else response :method_not_allowed, headers: {'Allow' => allowed_methods(@base_config)}, msg: "method #{@verb.upcase} not supported for collection URIs" end end
Private Instance Methods
get()
click to toggle source
# File lib/toast/collection_request.rb, line 31 def get if @config.via_get.nil? # not declared response :method_not_allowed, headers: {'Allow' => allowed_methods(@config)}, msg: "GET not configured" else begin range_start = @requested_range.start window = if (@requested_range.size.nil? || @requested_range.size > @config.max_window) @config.max_window else @requested_range.size end relation = call_handler(@config.via_get.handler, @uri_params) call_allow(@config.via_get.permissions, @auth, relation, @uri_params) if relation.is_a?(ActiveRecord::Relation) and relation.model.name == @config.base_model_class.name result = relation.limit(window).offset(range_start) count = relation.unscope(:select).select(:id).count headers = {"Content-Type" => @config.media_type} if count > 0 headers["Content-Range"] = "items=#{range_start}-#{range_start + result.length - 1}/#{count}" end response :ok, headers: headers, body: represent(result, @base_config), msg: "sent #{result.length} records of #{@base_config.model_class}" else # wrong class/model_class response :internal_server_error, msg: "collection method returned #{relation.class}, expected ActiveRecord::Relation of #{@config.base_model_class}" end rescue NotAllowed => error return response :unauthorized, msg: "not authorized by allow block in: #{error.source_location}" rescue BadRequest => error response :bad_request, msg: "`#{error.message}' in: #{error.source_location}", headers: {'X-Toast-Error' => error.code} rescue HandlerError => error return response :internal_server_error, msg: "exception raised in via_get handler: `#{error.orig_error.message}' in #{error.source_location}" rescue AllowError => error return response :internal_server_error, msg: "exception raised in allow block: `#{error.orig_error.message}' in #{error.source_location}" rescue => error response :internal_server_error, msg: "exception from via_get handler in: #{error.backtrace.first.sub(Rails.root.to_s+'/', '')}: #{error.message}" end end end
post()
click to toggle source
# File lib/toast/collection_request.rb, line 96 def post if @config.via_post.nil? # not declared response :method_not_allowed, headers: {'Allow' => allowed_methods(@config)}, msg: "POST not configured" else begin payload = JSON.parse(@request.body.read) call_allow(@config.via_post.permissions, @auth, nil, @uri_params) # remove all attributes not in writables from payload payload.delete_if do |attr,val| unless attr.to_sym.in?(@base_config.writables) Toast.logger.warn "<POST #{@request.fullpath}> received attribute `#{attr}' is not writable or unknown" true end end new_instance = call_handler(@config.via_post.handler, payload, @uri_params) if new_instance.persisted? response :created, headers: {"Content-Type" => @base_config.media_type}, msg: "created #{new_instance.class}##{new_instance.id}", body: represent(new_instance, @base_config) else message = new_instance.errors.count > 0 ? ": " + new_instance.errors.full_messages.join(',') : '' response :conflict, msg: "creation of #{new_instance.class} aborted#{message}" end rescue JSON::ParserError => error return response :internal_server_error, msg: "expect JSON body" rescue NotAllowed => error return response :unauthorized, msg: "not authorized by allow block in: #{error.source_location}" rescue BadRequest => error response :bad_request, msg: "`#{error.message}' in: #{error.source_location}", headers: {'X-Toast-Error' => error.code} rescue HandlerError => error return response :internal_server_error, msg: "exception raised in via_post handler: `#{error.orig_error.message}' in #{error.source_location}" rescue AllowError => error return response :internal_server_error, msg: "exception raised in allow block: `#{error.orig_error.message}' in #{error.source_location}" rescue => error response :internal_server_error, msg: "exception from via_post handler in: #{error.backtrace.first.sub(Rails.root.to_s+'/', '')}: #{error.message}" end end end