required_sub_paths.rb 1.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344
  1. module Mixin
  2. module RequiredSubPaths
  3. def self.included(_base)
  4. path = caller_locations(1..1).first.path
  5. sub_path = File.join(File.dirname(path), File.basename(path, '.rb'))
  6. eager_load_recursive(sub_path)
  7. end
  8. # Loads a directory recursively.
  9. # The specialty of this method is that it will first load all
  10. # files in a directory and then start with the sub directories.
  11. # This is needed since otherwise some parent namespaces might not
  12. # be initialized yet.
  13. #
  14. # The cause of this is that Rails autoload doesn't work properly
  15. # for same named classes or modules in different namespaces.
  16. # Here is a good description how autoload works:
  17. # http://urbanautomaton.com/blog/2013/08/27/rails-autoloading-hell/
  18. #
  19. # This avoids a) Rails autoloading issues and b) require '...' workarounds
  20. def self.eager_load_recursive(path)
  21. excluded = ['.', '..']
  22. sub_paths = []
  23. Dir.entries(path).each do |entry|
  24. next if excluded.include?(entry)
  25. sub_path = File.join(path, entry)
  26. if File.directory?(sub_path)
  27. sub_paths.push(sub_path)
  28. elsif sub_path =~ /\A(.*)\.rb\z/
  29. require_path = $1
  30. require_dependency(require_path)
  31. end
  32. end
  33. sub_paths.each do |sub_path|
  34. eager_load_recursive(sub_path)
  35. end
  36. end
  37. end
  38. end