是否有一种方法可以获得Rails应用程序中所有模型的集合?
基本上,我能做的是:-
Models.each do |model|
puts model.class.name
end
是否有一种方法可以获得Rails应用程序中所有模型的集合?
基本上,我能做的是:-
Models.each do |model|
puts model.class.name
end
当前回答
Module.constants.select { |c| (eval c).is_a?(Class) && (eval c) < ActiveRecord::Base }
其他回答
我寻找了很多方法,最后选择了这种方式:
in the controller:
@data_tables = ActiveRecord::Base.connection.tables
in the view:
<% @data_tables.each do |dt| %>
<br>
<%= dt %>
<% end %>
<br>
来源:http://portfo.li/rails/348561-how-can-one-list-all-database-tables-from-one-project
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
这将为您提供项目上的所有模型类。
假设所有模型都在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),尽管它有点慢。
万一有人无意中发现了这个问题,我有另一个解决方案,不依赖于dir读取或扩展Class类……
ActiveRecord::Base.send :subclasses
这将返回一个类数组。所以你可以这样做
ActiveRecord::Base.send(:subclasses).map(&:name)
以下是一个经过复杂Rails应用程序(支持Square的应用程序)审查的解决方案
def all_models
# must eager load all the classes...
Dir.glob("#{RAILS_ROOT}/app/models/**/*.rb") do |model_path|
begin
require model_path
rescue
# ignore
end
end
# simply return them
ActiveRecord::Base.send(:subclasses)
end
它采用了这篇文章中最好的答案,并将它们组合成最简单、最彻底的解决方案。当你的模型在子目录中时,可以使用set_table_name等。