module JSONAPI::ActsAsResourceController
Constants
- ALL_MEDIA_TYPES
- MEDIA_TYPE_MATCHER
Attributes
response_document[R]
Public Class Methods
included(base)
click to toggle source
# File lib/jsonapi/acts_as_resource_controller.rb, line 8 def self.included(base) base.extend ClassMethods base.include Callbacks base.cattr_reader :server_error_callbacks base.define_jsonapi_resources_callbacks :process_operations, :transaction end
Public Instance Methods
create()
click to toggle source
# File lib/jsonapi/acts_as_resource_controller.rb, line 30 def create process_request end
create_relationship()
click to toggle source
# File lib/jsonapi/acts_as_resource_controller.rb, line 34 def create_relationship process_request end
destroy()
click to toggle source
# File lib/jsonapi/acts_as_resource_controller.rb, line 46 def destroy process_request end
destroy_relationship()
click to toggle source
# File lib/jsonapi/acts_as_resource_controller.rb, line 50 def destroy_relationship process_request end
index()
click to toggle source
# File lib/jsonapi/acts_as_resource_controller.rb, line 18 def index process_request end
process_operation(operation)
click to toggle source
# File lib/jsonapi/acts_as_resource_controller.rb, line 139 def process_operation(operation) result = operation.process response_document.add_result(result, operation) end
process_operations(transactional) { || ... }
click to toggle source
# File lib/jsonapi/acts_as_resource_controller.rb, line 123 def process_operations(transactional) if transactional run_callbacks :transaction do ActiveRecord::Base.transaction do yield end end else begin yield rescue ActiveRecord::Rollback # Can't rollback without transaction, so just ignore it end end end
process_request()
click to toggle source
# File lib/jsonapi/acts_as_resource_controller.rb, line 78 def process_request @response_document = create_response_document unless verify_content_type_header && verify_accept_header render_response_document return end request_parser = JSONAPI::RequestParser.new( params, context: context, key_formatter: key_formatter, server_error_callbacks: (self.class.server_error_callbacks || [])) transactional = request_parser.transactional? begin process_operations(transactional) do run_callbacks :process_operations do request_parser.each(response_document) do |op| op.options[:serializer] = resource_serializer_klass.new( op.resource_klass, include_directives: op.options[:include_directives], fields: op.options[:fields], base_url: base_url, key_formatter: key_formatter, route_formatter: route_formatter, serialization_options: serialization_options, controller: self ) op.options[:cache_serializer_output] = !JSONAPI.configuration.resource_cache.nil? process_operation(op) end end if response_document.has_errors? raise ActiveRecord::Rollback end end rescue => e handle_exceptions(e) end render_response_document end
show()
click to toggle source
# File lib/jsonapi/acts_as_resource_controller.rb, line 22 def show process_request end
show_relationship()
click to toggle source
# File lib/jsonapi/acts_as_resource_controller.rb, line 26 def show_relationship process_request end
update()
click to toggle source
# File lib/jsonapi/acts_as_resource_controller.rb, line 42 def update process_request end
update_relationship()
click to toggle source
# File lib/jsonapi/acts_as_resource_controller.rb, line 38 def update_relationship process_request end
Private Instance Methods
base_meta()
click to toggle source
# File lib/jsonapi/acts_as_resource_controller.rb, line 226 def base_meta base_response_meta end
base_response_links()
click to toggle source
# File lib/jsonapi/acts_as_resource_controller.rb, line 230 def base_response_links {} end
base_response_meta()
click to toggle source
# File lib/jsonapi/acts_as_resource_controller.rb, line 222 def base_response_meta {} end
base_url()
click to toggle source
# File lib/jsonapi/acts_as_resource_controller.rb, line 154 def base_url @base_url ||= "#{request.protocol}#{request.host_with_port}#{Rails.application.config.relative_url_root}" end
context()
click to toggle source
override to set context
# File lib/jsonapi/acts_as_resource_controller.rb, line 200 def context {} end
create_response_document()
click to toggle source
# File lib/jsonapi/acts_as_resource_controller.rb, line 258 def create_response_document JSONAPI::ResponseDocument.new( key_formatter: key_formatter, base_meta: base_meta, base_links: base_response_links, request: request ) end
handle_exceptions(e)
click to toggle source
override this to process other exceptions Note: Be sure to either call super(e) or handle JSONAPI::Exceptions::Error
and raise unhandled exceptions
# File lib/jsonapi/acts_as_resource_controller.rb, line 269 def handle_exceptions(e) case e when JSONAPI::Exceptions::Error errors = e.errors when ActionController::ParameterMissing errors = JSONAPI::Exceptions::ParameterMissing.new(e.param).errors else if JSONAPI.configuration.exception_class_whitelisted?(e) raise e else if self.class.server_error_callbacks self.class.server_error_callbacks.each { |callback| safe_run_callback(callback, e) } end # Store exception for other middlewares request.env['action_dispatch.exception'] ||= e internal_server_error = JSONAPI::Exceptions::InternalServerError.new(e) Rails.logger.error { "Internal Server Error: #{e.message} #{e.backtrace.join("\n")}" } errors = internal_server_error.errors end end response_document.add_result(JSONAPI::ErrorsOperationResult.new(errors[0].status, errors), nil) end
key_formatter()
click to toggle source
Control by setting in an initializer:
JSONAPI.configuration.json_key_format = :camelized_key JSONAPI.configuration.route = :camelized_route
Override if you want to set a per controller key format. Must return an instance of a class derived from KeyFormatter
.
# File lib/jsonapi/acts_as_resource_controller.rb, line 214 def key_formatter JSONAPI.configuration.key_formatter end
media_types_for(header)
click to toggle source
# File lib/jsonapi/acts_as_resource_controller.rb, line 192 def media_types_for(header) (request.headers[header] || '') .scan(MEDIA_TYPE_MATCHER) .to_a .map(&:strip) end
render_response_document()
click to toggle source
# File lib/jsonapi/acts_as_resource_controller.rb, line 234 def render_response_document content = response_document.contents render_options = {} if response_document.has_errors? render_options[:json] = content else # Bypassing ActiveSupport allows us to use CompiledJson objects for cached response fragments render_options[:body] = JSON.generate(content) if (response_document.status == 201 && content[:data].class != Array) && content['data'] && content['data']['links'] && content['data']['links']['self'] render_options[:location] = content['data']['links']['self'] end end # For whatever reason, `render` ignores :status and :content_type when :body is set. # But, we can just set those values directly in the Response object instead. response.status = response_document.status response.headers['Content-Type'] = JSONAPI::MEDIA_TYPE render(render_options) end
resource_klass()
click to toggle source
# File lib/jsonapi/acts_as_resource_controller.rb, line 146 def resource_klass @resource_klass ||= resource_klass_name.safe_constantize end
resource_klass_name()
click to toggle source
# File lib/jsonapi/acts_as_resource_controller.rb, line 158 def resource_klass_name @resource_klass_name ||= "#{self.class.name.underscore.sub(/_controller$/, '').singularize}_resource".camelize end
resource_serializer_klass()
click to toggle source
# File lib/jsonapi/acts_as_resource_controller.rb, line 150 def resource_serializer_klass @resource_serializer_klass ||= JSONAPI::ResourceSerializer end
route_formatter()
click to toggle source
# File lib/jsonapi/acts_as_resource_controller.rb, line 218 def route_formatter JSONAPI.configuration.route_formatter end
safe_run_callback(callback, error)
click to toggle source
# File lib/jsonapi/acts_as_resource_controller.rb, line 297 def safe_run_callback(callback, error) begin callback.call(error) rescue => e Rails.logger.error { "Error in error handling callback: #{e.message} #{e.backtrace.join("\n")}" } internal_server_error = JSONAPI::Exceptions::InternalServerError.new(e) return JSONAPI::ErrorsOperationResult.new(internal_server_error.errors[0].code, internal_server_error.errors) end end
serialization_options()
click to toggle source
# File lib/jsonapi/acts_as_resource_controller.rb, line 204 def serialization_options {} end
valid_accept_media_type?()
click to toggle source
# File lib/jsonapi/acts_as_resource_controller.rb, line 184 def valid_accept_media_type? media_types = media_types_for('Accept') media_types.blank? || media_types.any? do |media_type| (media_type == JSONAPI::MEDIA_TYPE || media_type.start_with?(ALL_MEDIA_TYPES)) end end
verify_accept_header()
click to toggle source
# File lib/jsonapi/acts_as_resource_controller.rb, line 174 def verify_accept_header unless valid_accept_media_type? fail JSONAPI::Exceptions::NotAcceptableError.new(request.accept) end true rescue => e handle_exceptions(e) false end
verify_content_type_header()
click to toggle source
# File lib/jsonapi/acts_as_resource_controller.rb, line 162 def verify_content_type_header if ['create', 'create_relationship', 'update_relationship', 'update'].include?(params[:action]) unless request.content_type == JSONAPI::MEDIA_TYPE fail JSONAPI::Exceptions::UnsupportedMediaTypeError.new(request.content_type) end end true rescue => e handle_exceptions(e) false end