我使用标准导轨模型生成器创建了许多模型。 然后,一些模型得到了一个名为foo()的方法。
有没有一种简单的方法可以找出实现了foo()方法的生成模型的所有类名?
我的意思是programmaticaly,来自rails控制器,而不是来自控制台的源代码。
答案 0 :(得分:2)
Rails没有保留模型的索引,因此您只需要遍历app/models
目录。
以下是一个例子:
# Open the model directory
models_dir = Dir.open("#{RAILS_ROOT}/app/models")
# Walk directory entries
models = models_dir.collect do |filename|
# Get the name without extension.
# (And skip anything that isn't a Ruby file.)
next if not filename =~ /^(.+)\.rb$/
basename = $~[1]
# Now, get the model class
klass = basename.camelize.constantize
# And return it, if it implements our method
klass if klass.method_defined? :foo
end
# Remove nils
models.compact!
Rails在第一次引用模型和控制器时会懒洋洋地加载它们。这是使用Ruby的const_missing
方法完成的,您可以在active_support/dependencies.rb
中看到ActiveSupport中发生的所有魔法。
要详细说明上面发生的事情,您还需要知道类名和文件名是否已链接。 Rails希望ThingyBob
模型存在于thingy_bob.rb
中。在这两个名称之间进行转换的方法是使用String方法camelize
。 (反之亦然是underscore
方法。)这些String扩展也是ActiveSupport的一部分。
最后,使用ActiveSupport方法constantize
(也是String扩展),我们将字符串取消引用为常量。所以"ThingyBob".constantize
基本上只是写ThingyBob
;我们只需返回ThingyBob
课程。在上面的示例中,constantize
也会触发常规依赖加载魔法。
希望有助于揭开神秘面纱的神秘面纱。 :)