是否有一种方法可以获得Rails应用程序中所有模型的集合?
基本上,我能做的是:-
Models.each do |model|
puts model.class.name
end
是否有一种方法可以获得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
其他回答
编辑:看看评论和其他答案。有比这个更聪明的答案!或者尝试改进这个社区维基。
模型不会将自己注册到主对象,所以Rails没有模型列表。
但是您仍然可以在应用程序的models目录的内容中查找…
Dir.foreach("#{RAILS_ROOT}/app/models") do |model_path|
# ...
end
编辑:另一个(疯狂的)想法是使用Ruby反射来搜索每个扩展ActiveRecord::Base的类。我不知道你怎么列出所有的类…
编辑:只是为了好玩,我找到了一种列出所有职业的方法
Module.constants.select { |c| (eval c).is_a? Class }
编辑:终于成功地列出所有型号,而不查看目录
Module.constants.select do |constant_name|
constant = eval constant_name
if not constant.nil? and constant.is_a? Class and constant.superclass == ActiveRecord::Base
constant
end
end
如果你也想处理派生类,那么你需要测试整个超类链。我通过在Class类中添加一个方法来做到这一点:
class Class
def extend?(klass)
not superclass.nil? and ( superclass == klass or superclass.extend? klass )
end
end
def models
Module.constants.select do |constant_name|
constant = eval constant_name
if not constant.nil? and constant.is_a? Class and constant.extend? ActiveRecord::Base
constant
end
end
end
这似乎对我很管用:
Dir.glob(RAILS_ROOT + '/app/models/*.rb').each { |file| require file }
@models = Object.subclasses_of(ActiveRecord::Base)
Rails只在使用模型时加载模型,因此Dir。Glob行“需要”models目录中的所有文件。
一旦你在数组中有了模型,你可以做你想做的事情(例如在视图代码中):
<% @models.each do |v| %>
<li><%= h v.to_s %></li>
<% 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
我在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
我把它放在初始化式中,可以在任何地方调用它。防止不必要的鼠标使用。