module Grape::Transformations::Loader

Public Class Methods

class_by_name(name) click to toggle source

Return a class by its name, id it is not valid it returns nil @param [String], full class name @return [Object]

# File lib/grape/transformations/loader.rb, line 11
def self.class_by_name(name)
  name.safe_constantize
end
load_entities(root_api_path, relative_path_to_entities) click to toggle source

Loads all valid entities located in relative_path_to_entities dir, it verifies if entity is valid and if it is associated with valid class. When this process is accomplished is saved a hash with classname as a key and its associated entity as a value (using Rails.cache) @param root_api_path [String], path to api dir @param relative_path_to_entities [String], relative path to entities

# File lib/grape/transformations/loader.rb, line 21
def self.load_entities(root_api_path, relative_path_to_entities)
  available_entities = {}
  path_to_entities = File.join(root_api_path, relative_path_to_entities)
  api_entities_namespace = relative_path_to_entities.split('/').map { |module_name| module_name.gsub(' ','_').camelcase }.join('::')
  Dir.glob(File.join(path_to_entities, '**', '*.rb')).each do |filename|
    relative_path = filename.sub("#{path_to_entities}/", '')
    class_hierarchy = relative_path.split("/").map {|filename| filename.gsub(' ','_').camelcase.sub('.rb','')}
    class_name = class_hierarchy.join('::')
    entity_name = "#{api_entities_namespace}::#{class_name}"
    klass = class_by_name class_name
    entity = class_by_name entity_name

    # If there is a one to one match from Entities::..::Entity to ..::Klass, use it
    if entity && klass
      available_entities[class_name] = entity_name
    else
      # If not, try to find a "Default" transformation entity class
      # namespaced in the pluralized klass

      # An entity has to exist
      if entity
        # example: ['Admin', 'Billing', 'Addresses'], 'Default' = ['Admin', 'Billing', 'Addresses', 'Default']
        *transformation_hierarchy, transformation_name = class_hierarchy

        if transformation_name == 'Default'

          # example: ['Admin', 'Billing'], 'Addresses' = ['Admin', 'Billing', 'Addresses']
          *class_name_hierarchy, pluralized_transformable_class_name = transformation_hierarchy
          # example: 'Address' = "Addresses".singularize
          transformable_class_name = pluralized_transformable_class_name.singularize
          # example: Admin::Billing::Address

          class_name_hierarchy << transformable_class_name
          class_name = class_name_hierarchy.join('::')
          klass = class_by_name class_name
          # example: Admin::Billing::Address

          # a matching class was found
          if klass
            available_entities[class_name] = entity_name
          else
            # The entity is just an entity, no matching class... however seems like
            # conventions were not properly followed
          end

        else
          # No one to one match or Default transformation found, no entity used
        end
      else
        puts "[WARN] - Conventions not followed? - Entity #{entity_name} was not found at #{filename}, please check"
      end
    end

  end
  register_entities available_entities
end

Private Class Methods

register_entities(available_entities) click to toggle source

Saves entities in cache by using Rails.cache approach

# File lib/grape/transformations/loader.rb, line 80
def self.register_entities(available_entities)
  Rails.cache.delete(:registered_entities) # make sure it is clean
  Rails.cache.fetch(:registered_entities){ available_entities }
end