如何在不手动加载类的情况下获取命名空间中的所有类?

时间:2012-11-13 09:25:46

标签: ruby ruby-on-rails-3 module namespaces

我正在寻找一种方法来列出模块(命名空间)中定义的所有类。 以下是有关此问题的类似问题: How to get all class names in a namespace in Ruby?

但是看到最后一个回复,Module.constants为空,直到调用/加载类。有没有办法在不手动引用每个类的情况下执行此操作?

我正在尝试在Rails 3.2中使用此功能,我发现的唯一方法是在初始化程序中要求每个类(没有尝试但仍需要手动输入......)。

提前感谢您的时间。

3 个答案:

答案 0 :(得分:2)

您可以在命名空间目录中对文件进行全局处理:

Dir.glob('/path/to/namespaced/directory/*').collect{|file_path| File.basename(file_path, '.rb').constantize}

所以在Rails初始化文件或模型中你可以这样做:

Dir.glob(File.join(Rails.root, "app", "models", "my_namespace", "*")).collect{|file_path| File.basename(file_path, '.rb').constantize}

答案 1 :(得分:1)

在Bryan提供的基础上,你可以使用它来从特定的父命名空间中获取常量/类,即使是以一些字符串开头/结尾的文件名/类名:

require 'pathname'

# make this the directory you are autoloading from
autoload_dir = File.join(Rails.application.root, 'app', 'models')

# this will return FooBar::BarFoo::**::*Boo constants and autoload them
Dir.glob(File.join(autoload_dir, 'foo_bar', 'bar_foo', '**', '*_boo.rb')).collect{|pathname| Pathname.new(pathname.chomp('.rb')).relative_path_from(Pathname.new(autoload_dir)).to_s.camelize.constantize}

答案 2 :(得分:0)

Bryan Liff简短而优雅的答案几乎是正确的,但却引发了错误。相反,尝试:

Dir.glob(File.join(Rails.root, "app", "models", "my_namespace", "*")).collect{|file_path| File.basename(file_path, '.rb').camelize.constantize}

请注意camelize的使用。我会在评论中发布这个,但没有足够的声誉这样做。