Skip to content

Commit

Permalink
Simplify jsonapi_class configuration
Browse files Browse the repository at this point in the history
Adds
• JSONAPI::Rails::SerializableClassMapping class
  Overriding Hash’s lookup can be confusing without creating an
  descendent class.
  - Old behavior
    inferrer.class == Hash
    Doesn’t make it obvious that there’s custom behavior
  - New behavior
    inferrer.class == JSONAPI::Rails::SerializableClassMapping
    Now it’s obvious where to look for the unusual behavior
  This setup also allows us to define the default mappings and the
  lookup behavior in separate configuration options
• configuration options for
  1. jsonapi_class_mapper
  2. jsonapi_class_mappings
  3. jsonapi_errors_class_mapper
    (fallback to jsonapi_class_mapper if nil)
  4. jsonapi_errors_class_mappings
Removes
• configration options for
  1. jsonapi_class
  2. jsonapi_errors_class
  • Loading branch information
JoeWoodward committed Sep 1, 2018
1 parent 14a9421 commit d605448
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 27 deletions.
27 changes: 15 additions & 12 deletions lib/generators/jsonapi/initializer/templates/initializer.rb
Original file line number Diff line number Diff line change
@@ -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.
Expand Down
27 changes: 14 additions & 13 deletions lib/jsonapi/rails/configuration.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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,
Expand Down
13 changes: 11 additions & 2 deletions lib/jsonapi/rails/controller/hooks.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
require 'jsonapi/rails/configuration'
require 'jsonapi/rails/serializable_class_mapping'

module JSONAPI
module Rails
Expand All @@ -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.
Expand Down
11 changes: 11 additions & 0 deletions lib/jsonapi/rails/serializable_class_mapping.rb
Original file line number Diff line number Diff line change
@@ -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

0 comments on commit d605448

Please sign in to comment.