【问题标题】:List of Classes in Ruby On RailsRuby On Rails 中的类列表
【发布时间】:2014-11-17 19:20:07
【问题描述】:

我需要列出我的模型文件夹中存在的所有类(如果可能,带有属性),我通过 ActiveRecord 成功完成了它,但我找不到任何跨 ORM 和跨 DB 的解决方案。


一个例子比我的话容易理解:

文件结构

 app
. models
.. user.rb
.. post.rb
.. comment.rb

内部文件

class User
  ...
end

class Post
  ...
end

class Comment
  ...
end

预期

[User,Post,Comment]

现有但不完整的解决方案

现在,我列出了这些类,这要归功于一小段代码

model_name = []
ActiveRecord::Base.subclasses.each do |t|
  model_name << t.name.camelize
end
model_name

问题

我正在寻找相同类型的方法,但没有 ActiveRecord。 无论 ORM 或数据库的类型如何,我都需要访问类列表(如果可能,请使用属性)。 我考虑过解析模型的文件夹,但这对我来说似乎不是一个好的解决方案。

您对一些解决方案有什么想法吗?

【问题讨论】:

    标签: ruby-on-rails ruby class activerecord mongoid


    【解决方案1】:

    我能想到几个攻角:

    1. 大多数 ORM 具有与 ActiveRecord 类似的模式,这意味着模型类需要继承(或包含)某些基类,然后您可以对后代进行内省(例如 Sequel::Model.decendants 用于 sequel
    2. 如果您的所有模型都在已知的Module(命名空间)下声明,您可以使用constants 方法列出在特定模块下声明的类

      MyModels.constants
      # => [MyModels::User,MyModels::Post,MyModels::Comment]
      
    3. 如果您可以控制类的加载时间(即它们不会自动加载),则可以在加载模型之前和之后枚举对象空间中的类,如下所示:

      classes_before = Set.new
      ObjectSpace.each_object do |cl| 
        classes_before << cl if cl.class == Class
      end
      Dir.glob('app/models/*.rb').each do |model|
        require model
      end
      classes_after = Set.new
      ObjectSpace.each_object do |cl| 
        classes_after << cl if cl.class == Class
      end
      model_classes = classes_after - classes_before
      
    4. 如果你知道所有的模型类都是用rails idioms写的(每个文件中只有一个类,文件名是类名的snake_case),你也可以简单的收集文件名在models 文件夹下:

      Dir.glob('app/models/*.rb').map do |file|
        file[/app\/models\/(.*)\.rb/, 1].camelize
      end
      

    【讨论】:

    • 感谢您的回答,您让我相信毕竟没有神奇的解决方案,只有不同类型的修复才能给我带来预期的结果。我忘了提到它是为了在 gem 中使用它,所以它会很棘手,但由于你给我的不同解决方案,我会在这些解决方案中找到最好的。
    猜你喜欢
    • 2018-11-07
    • 2015-03-02
    • 2010-11-23
    • 1970-01-01
    • 2011-05-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多