class Yaks::DefaultPolicy
Constants
- DEFAULTS
Default policy options.
Attributes
@!attribute [r]
@return [Hash]
Public Class Methods
@param options [Hash] options
# File lib/yaks/default_policy.rb, line 18 def initialize(options = {}) @options = DEFAULTS.merge(options) end
Public Instance Methods
# File lib/yaks/default_policy.rb, line 103 def derive_mapper_from_association(association) @options[:namespace].const_get("#{camelize(association.singular_name)}Mapper") end
Derives a mapper from the given collection.
@param collection [Object] @return [Class] A mapper, typically a subclass of Yaks::Mapper
# File lib/yaks/default_policy.rb, line 41 def derive_mapper_from_collection(collection) if m = collection.first name = "#{m.class.name.split('::').last}CollectionMapper" begin return @options[:namespace].const_get(name) rescue NameError # rubocop:disable Lint/HandleExceptions end end begin return @options[:namespace].const_get(:CollectionMapper) rescue NameError # rubocop:disable Lint/HandleExceptions end CollectionMapper end
Derives a mapper from the given item. This item should not be a collection.
@param item [Object] @return [Class] A mapper, typically a subclass of Yaks::Mapper
@raise [RuntimeError] only occurs when no mapper is found for the given item.
# File lib/yaks/default_policy.rb, line 63 def derive_mapper_from_item(item) klass = item.class namespaces = klass.name.split("::")[0...-1] begin return build_mapper_class(namespaces, klass) rescue NameError klass = next_class_for_lookup(item, namespaces, klass) retry if klass end raise_mapper_not_found(item) end
Main point of entry for mapper derivation. Calls derive_mapper_from_collection
or derive_mapper_from_item
depending on the model.
@param model [Object] @return [Class] A mapper, typically a subclass of Yaks::Mapper
@raise [RuntimeError] occurs when no mapper is found
# File lib/yaks/default_policy.rb, line 30 def derive_mapper_from_object(model) mapper = detect_configured_mapper_for(model) return mapper if mapper return derive_mapper_from_collection(model) if model.respond_to? :to_ary derive_mapper_from_item(model) end
@param association [Yaks::Mapper::Association] @return [String]
# File lib/yaks/default_policy.rb, line 109 def derive_rel_from_association(association) expand_rel(association.name) end
Derive the mapper type name from a collection
This inspects the first element of the collection, so it requires a collection with truthy elements. Will return `nil` if the collection has no truthy elements.
@param [#first] collection
@return [String|nil]
@raise [NameError]
# File lib/yaks/default_policy.rb, line 98 def derive_type_from_collection(collection) return if collection.none? derive_type_from_mapper_class(derive_mapper_from_object(collection.first)) end
Derive the a mapper type name
This returns the 'system name' for a mapper, e.g. ShowEventMapper => show_event.
@param [Class] mapper_class
@return [String]
# File lib/yaks/default_policy.rb, line 83 def derive_type_from_mapper_class(mapper_class) underscore(mapper_class.name.split('::').last.sub(/Mapper$/, '')) end
@param relname [String] @return [String]
# File lib/yaks/default_policy.rb, line 115 def expand_rel(relname) URITemplate.new(@options[:rel_template]).expand(rel: relname) end
Private Instance Methods
# File lib/yaks/default_policy.rb, line 121 def build_mapper_class(namespaces, klass) mapper_class = "#{klass.name.split('::').last}Mapper" [*namespaces, mapper_class].inject(@options[:namespace]) do |namespace, module_or_class| namespace.const_get(module_or_class, false) end end
# File lib/yaks/default_policy.rb, line 142 def detect_configured_mapper_for(object) @options[:mapper_rules].each do |rule, mapper_class| return mapper_class if rule === object # rubocop:disable Style/CaseEquality end nil end
# File lib/yaks/default_policy.rb, line 128 def next_class_for_lookup(item, namespaces, klass) superclass = klass.superclass return superclass if superclass < Object return nil if namespaces.empty? namespaces.clear item.class end
# File lib/yaks/default_policy.rb, line 136 def raise_mapper_not_found(item) namespace = "#{@options[:namespace]}::" unless Object.equal?(@options[:namespace]) mapper_class = "#{namespace}#{item.class}Mapper" raise "Failed to find a mapper for #{item.inspect}. Did you mean to implement #{mapper_class}?" end