是否有一种方法可以获得Rails应用程序中所有模型的集合?

基本上,我能做的是:-

Models.each do |model|
  puts model.class.name
end

当前回答

我在Rails 4中尝试了很多这样的答案,但都没有成功(哇,看在上帝的份上,他们改变了一两件事),所以我决定添加我自己的答案。调用ActiveRecord::Base的那些。连接和拉表名工作,但没有得到我想要的结果,因为我隐藏了一些模型(在app/models/内的文件夹中),我不想删除:

def list_models
  Dir.glob("#{Rails.root}/app/models/*.rb").map{|x| x.split("/").last.split(".").first.camelize}
end

我把它放在初始化式中,可以在任何地方调用它。防止不必要的鼠标使用。

其他回答

Module.constants.select { |c| (eval c).is_a?(Class) && (eval c) < ActiveRecord::Base }

我还不能评论,但我认为sj26的答案应该是首要答案。提示一下:

Rails.application.eager_load! unless Rails.configuration.cache_classes
ActiveRecord::Base.descendants

我认为@hnovick的解决方案是一个很酷的,如果你没有表的模型。这个解决方案也可以在开发模式下工作

但我的方法略有不同

ActiveRecord::Base.connection.tables.map{|x|x.classify.safe_constantize}.compact

分类应该能从字符串中正确地给出类名。safe_constantise确保您可以安全地将其转换为类,而不会抛出异常。如果您的数据库表不是模型,则需要这样做。紧凑,以便删除枚举中的任何nil。

万一有人无意中发现了这个问题,我有另一个解决方案,不依赖于dir读取或扩展Class类……

ActiveRecord::Base.send :subclasses

这将返回一个类数组。所以你可以这样做

ActiveRecord::Base.send(:subclasses).map(&:name)

刚刚看到这个,因为我需要打印所有模型的属性(基于@Aditya Sanghi的评论):

ActiveRecord::Base.connection.tables.map{|x|x.classify.safe_constantize}.compact.each{ |model| print "\n\n"+model.name; model.new.attributes.each{|a,b| print "\n#{a}"}}