module RailsModuleUnification::DependencyExtensions
Constants
- QUALIFIED_NAME_SPLIT
split on any of the resource suffixes OR the ruby namespace seperator
- RESOURCE_SUFFIXES
Join all the suffix names together with an “OR” operator
- RESOURCE_SUFFIX_NAMES
Public Instance Methods
# File lib/rails_module_unification/active_support/dependency_extensions.rb, line 20 def load_from_path(file_path, qualified_name, from_mod, const_name) expanded = File.expand_path(file_path) expanded.sub!(/\.rb\z/, '') if loading.include?(expanded) raise "Circular dependency detected while autoloading constant #{qualified_name}" else require_or_load(expanded, qualified_name) unless from_mod.const_defined?(const_name, false) raise LoadError, "Unable to autoload constant #{qualified_name}, expected #{file_path} to define it" end return from_mod.const_get(const_name) end end
Load the constant named const_name
which is missing from from_mod
. If it is not possible to load the constant into from_mod, try its parent module using const_missing
.
# File lib/rails_module_unification/active_support/dependency_extensions.rb, line 118 def load_missing_constant(from_mod, const_name) # always default to the actual implementation super rescue LoadError, NameError => e load_missing_constant_error(from_mod, const_name, e) end
the heavy liftign of Rails Module Unification is just adding some additional pathfinding / constat lookup logic when the default (super) can't find what needs to be found
@param [Class] from_mod - parent module / class that const_name may be a part of @param [Symbol] const_name - potential constant to lookup under from_mod @param [Exception] e - exception from previous error
# File lib/rails_module_unification/active_support/dependency_extensions.rb, line 132 def load_missing_constant_error(from_mod, const_name, e) # examples # - Api::PostsController # - PostsController qualified_name = qualified_name_for(from_mod, const_name) file_path = resource_path_from_qualified_name(qualified_name) begin return load_from_path(file_path, qualified_name, from_mod, const_name) if file_path rescue LoadError, NameError => e # Recurse! # not found, check the parent at_the_top = from_mod.parent == from_mod return load_missing_constant_error(from_mod.parent, const_name, e) unless at_the_top raise e end name_error = NameError.new(e.message) name_error.set_backtrace(caller.reject { |l| l.starts_with? __FILE__ }) raise name_error end
A look for the possible places that various qualified names could be
@note The Lookup Rules:
- all resources are plural - file_names can either be named after the type or traditional ruby/rails nameing i.e.: posts_controller.rb vs controller.rb - regular namespacing still applies. i.e: Api::V2::CategoriesController should be in api/v2/categories/controller.rb
@note The Pattern:
- namespace_a - api - namespace_b - v2 - resource_name (plural) - posts - file_type.rb - controller.rb (or posts_controller.rb) - operations.rb (or post_operations.rb) - folder_type - operations/ (or post_operations/) - related namespaced classes - create.rb
All examples assume default resource directory (“resources”) and show the order of lookup
@example Api::PostsController
Possible Locations - api/posts/controller.rb - api/posts/posts_controller.rb
@example Api::PostSerializer
Possible Locations - api/posts/serializer.rb - api/posts/post_serializer.rb
@example Api::PostOperations::Create
Possible Locations - api/posts/operations/create.rb - api/posts/post_operations/create.rb
@example Api::V2::CategoriesController
Possible Locations - api/v2/categories/controller.rb - api/v2/categories/categories_controller.rb
@param [String] qualified_name fully qualified class/module name to find the file location for
# File lib/rails_module_unification/active_support/dependency_extensions.rb, line 79 def resource_path_from_qualified_name(qualified_name) namespace, resource_name, resource_type, named_resource_type, class_path = ResourceParts.from_name(qualified_name) # build all the possible places that this file could be path_options = [ # api/v2/posts/operations/update to_path(namespace, resource_name, resource_type, class_path), # api/v2/posts/post_operations/update to_path(namespace, resource_name, named_resource_type, class_path), # api/v2/posts/posts_controller to_path(namespace, resource_name, named_resource_type), # api/v2/posts/controller to_path(namespace, resource_name, resource_type) ].uniq file_path = '' path_options.each do |path_option| file_path = search_for_file(path_option) break if file_path.present? end file_path end
# File lib/rails_module_unification/active_support/dependency_extensions.rb, line 111 def to_path(*args) args.flatten.reject(&:blank?).map(&:underscore).join('/') end