diff --git a/lib/generators/jsonapi/initializer/templates/initializer.rb b/lib/generators/jsonapi/initializer/templates/initializer.rb index 36a9774..75e0cb3 100644 --- a/lib/generators/jsonapi/initializer/templates/initializer.rb +++ b/lib/generators/jsonapi/initializer/templates/initializer.rb @@ -1,19 +1,22 @@ JSONAPI::Rails.configure do |config| - # # Set a default serializable class mapping. - # config.jsonapi_class = Hash.new { |h, k| - # names = k.to_s.split('::') + # # Set a default serializable class mapper + # config.jsonapi_class_mapper = -> (class_name) do + # names = class_name.to_s.split('::') # klass = names.pop - # h[k] = [*names, "Serializable#{klass}"].join('::').safe_constantize + # [*names, "Serializable#{klass}"].join('::').safe_constantize + # end + # + # # Set any default serializable class mappings + # config.jsonapi_class_mappings = { # } # - # # Set a default serializable class mapping for errors. - # config.jsonapi_errors_class = Hash.new { |h, k| - # names = k.to_s.split('::') - # klass = names.pop - # h[k] = [*names, "Serializable#{klass}"].join('::').safe_constantize - # }.tap { |h| - # h[:'ActiveModel::Errors'] = JSONAPI::Rails::SerializableActiveModelErrors - # h[:Hash] = JSONAPI::Rails::SerializableErrorHash + # # Set a default serializable class mapper for errors. + # config.jsonapi_errors_class_mapper = config.jsonapi_class_mapper.dup + # + # # Set any default serializable class errors mappings + # config.jsonapi_errors_class_mappings = { + # :'ActiveModel::Errors' => JSONAPI::Rails::SerializableActiveModelErrors, + # :Hash => JSONAPI::Rails::SerializableErrorHash # } # # # Set a default JSON API object. diff --git a/lib/jsonapi/rails/configuration.rb b/lib/jsonapi/rails/configuration.rb index 7a7f76f..6e5b8bb 100644 --- a/lib/jsonapi/rails/configuration.rb +++ b/lib/jsonapi/rails/configuration.rb @@ -7,22 +7,21 @@ class Configuration < ActiveSupport::InheritableOptions; end # @private module Configurable - DEFAULT_JSONAPI_CLASS = Hash.new do |h, k| - names = k.to_s.split('::') + DEFAULT_JSONAPI_CLASS_MAPPER = -> (class_name) do + names = class_name.to_s.split('::') klass = names.pop - h[k] = [*names, "Serializable#{klass}"].join('::').safe_constantize - end.freeze + [*names, "Serializable#{klass}"].join('::').safe_constantize + end - DEFAULT_JSONAPI_ERRORS_CLASS = DEFAULT_JSONAPI_CLASS.dup.merge!( - 'ActiveModel::Errors'.to_sym => - JSONAPI::Rails::SerializableActiveModelErrors, - 'Hash'.to_sym => JSONAPI::Rails::SerializableErrorHash - ).freeze + DEFAULT_JSONAPI_CLASS_MAPPINGS = {}.freeze - DEFAULT_JSONAPI_OBJECT = { - version: '1.0' + DEFAULT_JSONAPI_ERROR_CLASS_MAPPINGS = { + :'ActiveModel::Errors' => JSONAPI::Rails::SerializableActiveModelErrors, + :Hash => JSONAPI::Rails::SerializableErrorHash }.freeze + DEFAULT_JSONAPI_OBJECT = { version: '1.0' }.freeze + DEFAULT_JSONAPI_CACHE = ->() { nil } DEFAULT_JSONAPI_EXPOSE = lambda { @@ -42,8 +41,10 @@ module Configurable DEFAULT_LOGGER = Logger.new(STDERR) DEFAULT_CONFIG = { - jsonapi_class: DEFAULT_JSONAPI_CLASS, - jsonapi_errors_class: DEFAULT_JSONAPI_ERRORS_CLASS, + jsonapi_class_mapper: DEFAULT_JSONAPI_CLASS_MAPPER, + jsonapi_class_mappings: DEFAULT_JSONAPI_CLASS_MAPPINGS, + jsonapi_errors_class_mapper: nil, + jsonapi_errors_class_mappings: DEFAULT_JSONAPI_ERROR_CLASS_MAPPINGS, jsonapi_cache: DEFAULT_JSONAPI_CACHE, jsonapi_expose: DEFAULT_JSONAPI_EXPOSE, jsonapi_fields: DEFAULT_JSONAPI_FIELDS, diff --git a/lib/jsonapi/rails/controller/hooks.rb b/lib/jsonapi/rails/controller/hooks.rb index d18a6c6..5ffcd97 100644 --- a/lib/jsonapi/rails/controller/hooks.rb +++ b/lib/jsonapi/rails/controller/hooks.rb @@ -1,4 +1,5 @@ require 'jsonapi/rails/configuration' +require 'jsonapi/rails/serializable_class_mapping' module JSONAPI module Rails @@ -11,14 +12,22 @@ module Hooks # Overridden by the `class` renderer option. # @return [Hash{Symbol=>Class}] def jsonapi_class - JSONAPI::Rails.config[:jsonapi_class].dup + JSONAPI::Rails::SerializableClassMapping.new( + JSONAPI::Rails.config[:jsonapi_class_mappings].dup, + &JSONAPI::Rails.config[:jsonapi_class_mapper] + ) end # Hook for serializable class mapping (for errors). # Overridden by the `class` renderer option. # @return [Hash{Symbol=>Class}] def jsonapi_errors_class - JSONAPI::Rails.config[:jsonapi_errors_class].dup + class_mapper = + JSONAPI::Rails.config[:jsonapi_errors_class_mapper]&.dup || + JSONAPI::Rails.config[:jsonapi_class_mapper].dup + JSONAPI::Rails::SerializableClassMapping.new( + JSONAPI::Rails.config[:jsonapi_errors_class_mappings], &class_mapper + ) end # Hook for the jsonapi object. diff --git a/lib/jsonapi/rails/serializable_class_mapping.rb b/lib/jsonapi/rails/serializable_class_mapping.rb new file mode 100644 index 0000000..7e576f3 --- /dev/null +++ b/lib/jsonapi/rails/serializable_class_mapping.rb @@ -0,0 +1,11 @@ +module JSONAPI + module Rails + class SerializableClassMapping < Hash + def initialize(default_mappings = {}, &block) + super() do |hash, class_name_sym| + hash[class_name_sym] = yield(class_name_sym.to_s).safe_constantize + end + end + end + end +end