是否有一种方法可以获得Rails应用程序中所有模型的集合?
基本上,我能做的是:-
Models.each do |model|
puts model.class.name
end
是否有一种方法可以获得Rails应用程序中所有模型的集合?
基本上,我能做的是:-
Models.each do |model|
puts model.class.name
end
当前回答
Rails5的模型现在是ApplicationRecord的子类,所以要获得应用程序中所有模型的列表,你需要:
ApplicationRecord.descendants.collect { |type| type.name }
或更短:
ApplicationRecord.descendants.collect(&:name)
如果你在开发模式下,你需要在以下情况之前加载模型:
Rails.application.eager_load!
其他回答
万一有人无意中发现了这个问题,我有另一个解决方案,不依赖于dir读取或扩展Class类……
ActiveRecord::Base.send :subclasses
这将返回一个类数组。所以你可以这样做
ActiveRecord::Base.send(:subclasses).map(&:name)
一行:Dir['app/models/\*.rb']。map {|f|文件。basename .camelize (f,“。*”)。constantize}
确保在调用后代之前加载你的应用程序,这样所有的类都被加载了:
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
假设所有模型都在app/models中,并且你的服务器上有grep和awk(大多数情况下),
# extract lines that match specific string, and print 2nd word of each line
results = `grep -r "< ActiveRecord::Base" app/models/ | awk '{print $2}'`
model_names = results.split("\n")
它比Rails.application.eager_load快!或者用Dir遍历每个文件。
编辑:
这种方法的缺点是它忽略了间接继承自ActiveRecord的模型(例如FictionalBook < Book)。最可靠的方法是Rails.application.eager_load!;ActiveRecord::Base.descendants.map(&:name),尽管它有点慢。
在Rails 6中,Zetiwerk成为默认的代码加载器。
对于快速加载,请尝试:
Zeitwerk::Loader.eager_load_all
Then
ApplicationRecord.descendants