简体   繁体   中英

List of Classes in Ruby On Rails

I need to list all Class (with attributes if possible) present in my model folder and I succeed to do it through ActiveRecord but I can't find any solutions cross-ORM and cross-DB.


An example is a lot easier to understand than my words:

Files Structure

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

Inside Files

class User
  ...
end

class Post
  ...
end

class Comment
  ...
end

Expected

[User,Post,Comment]

Existing but uncomplete solution

For now, I'm listing the classes thanks to than small piece of Code

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

Question

I'm looking for to the same type of method but without ActiveRecord. I need to access the list of classes (with attributes if possible) no matter the ORM or the type of the DB. I thought about parsing models' folder but it does not seems to be a good solution to me.

Have you an idea about some solutions ?

There are a few angles of attack I can think of:

  1. Most ORMs have a similar pattern as ActiveRecord, which means that model classes need to inherit from (or include) some base class, which you can then introspect for decendants (for example Sequel::Model.decendants for sequel
  2. If all of your models are declared under a known Module (namespace), you can list the classes declared under a specific module using the constants method

     MyModels.constants # => [MyModels::User,MyModels::Post,MyModels::Comment] 
  3. If you have control on the timing of the loading of the classes (ie they are not autoloaded), you can enumerate the classes in the object space before and after loading your models, something like this:

     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. If you know the all the model classes are written by rails idioms (single class in each file, with the name of the file as a snake_case of the name of the class), you can also simply collect the names of the files under the models folder:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM