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

基本上,我能做的是:-

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

当前回答

确保在调用后代之前加载你的应用程序,这样所有的类都被加载了:

Rails.application.eager_load! unless Rails.application.config.eager_load

ApplicationRecord.descendants.each do |clazz|
  # do something with clazz, e.g. User, Event, Attendance, etc.
end

其他回答

这适用于Rails 3.2.18

Rails.application.eager_load!

def all_models
  models = Dir["#{Rails.root}/app/models/**/*.rb"].map do |m|
    m.chomp('.rb').camelize.split("::").last
  end
end
Dir.foreach("#{Rails.root.to_s}/app/models") do |model_path|
  next unless model_path.match(/.rb$/)
  model_class = model_path.gsub(/.rb$/, '').classify.constantize
  puts model_class
end

这将为您提供项目上的所有模型类。

Rails 3、4和5的完整答案是:

如果cache_classes是关闭的(在开发中默认是关闭的,但在生产中是打开的):

Rails.application.eager_load!

然后:

ActiveRecord::Base.descendants

这将确保加载应用程序中的所有模型,无论它们位于何处,并且也加载了您使用的任何提供模型的gem。

这应该也适用于从ActiveRecord::Base继承的类,如Rails 5中的ApplicationRecord,并只返回后代的子树:

ApplicationRecord.descendants

如果您想了解更多关于这是如何完成的,请查看ActiveSupport:: descent stracker。

一行:Dir['app/models/\*.rb']。map {|f|文件。basename .camelize (f,“。*”)。constantize}

def load_models_in_development
  if Rails.env == "development"
    load_models_for(Rails.root)
    Rails.application.railties.engines.each do |r|
      load_models_for(r.root)
    end
  end
end

def load_models_for(root)
  Dir.glob("#{root}/app/models/**/*.rb") do |model_path|
    begin
      require model_path
    rescue
      # ignore
    end
  end
end