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

基本上,我能做的是:-

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

当前回答

这对我很管用。特别感谢上面所有的帖子。这将返回所有模型的集合。

models = []

Dir.glob("#{Rails.root}/app/models/**/*.rb") do |model_path|
  temp = model_path.split(/\/models\//)
  models.push temp.last.gsub(/\.rb$/, '').camelize.constantize rescue nil
end

其他回答

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

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

ActiveRecord::Base.send :subclasses

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

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

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

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
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

如果你只需要类名:

ActiveRecord::Base.descendants.map {|f| puts f}

只需在Rails控制台中运行它,仅此而已。好运!

编辑:@sj26是正确的,你需要在调用后代之前先运行这个:

Rails.application.eager_load!