获取已实施某种方法的所有模型

时间:2010-02-06 16:07:44

标签: ruby-on-rails object methods

我使用标准导轨模型生成器创建了许多模型。 然后,一些模型得到了一个名为foo()的方法。

有没有一种简单的方法可以找出实现了foo()方法的生成模型的所有类名?

我的意思是programmaticaly,来自rails控制器,而不是来自控制台的源代码。

1 个答案:

答案 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也会触发常规依赖加载魔法。

希望有助于揭开神秘面纱的神秘面纱。 :)