Как преобразовать имя таблицы ActiveRecord в имя класса модели

Есть ли возможность правильно преобразовать имя таблицы ActiveRecord в имя класса модели? Я нашел один хак

def model_for_table(table_name)
  table_name.classify.constantize
end

но поскольку мы используем set_table_name для многих наших моделей, это не сработает. Есть ли способ сделать это?

Ответы

Ответ 1

Я сделал это!

Возвращает хэш в виде "table_name" = > "model_class_name".

Hash[ObjectSpace.enum_for(:each_object, class << ActiveRecord::Base; 
    self; end).to_a.reject{|c| c == ActiveRecord::Base}.collect{
    |c| [c.table_name, c.name]}]

EDIT: Лучшая версия (работает только с Rails 3):

Hash[ActiveRecord::Base.send(:descendants).collect{|c| [c.table_name, c.name]}]

Обратите внимание, что не все ваши классы моделей всегда загружаются. Чтобы загрузить их все, прежде чем создавать такой хэш, выполните следующие действия:

Dir.foreach("#{RAILS_ROOT}/app/models") { |f| require f if f =~ /.*\.rb/ }

Ницца.

Ответ 2

ObjectSpace.each_object(Class).select{ |klass| 
  klass < ActiveRecord::Base 
}.index_by(&:table_name)

Это не самая быстрая вещь в мире, хотя

Ответ 3

Можно сделать это в рельсах 3:

ActiveRecord::Base.descendants.collect{|c| [c.table_name, c.name]}