2010-08-01
■[Ruby on Rails] Model クラスの一覧を取得する方法
Model クラスの一覧を取得するには、以下のアプローチが考えられます。
- テーブル名からクラス名を求める方法
- 全クラスから ActiveRecord::Base を継承するクラスを抽出する方法
テーブル名からクラス名を求める方法
方法
tables = ActiveRecord::Base.connection.tables
=> ["schema_migrations", "users", "photos"]
models = tables.map{|table| Object.const_get(table.classify) rescue nil}.compact
=> User(id: integer, email: string, created_at: datetime), Photo(id: integer, us
er_id: integer, file_name: string, created_at: datetime)]
問題
以下のように table_name でテーブル名を設定している(クラス名がテーブル名の単数形になっていない)クラスを取得することが出来ません。
class Image self.table_name = 'photos' end
対策
クラス名とテーブル名を Rails の規約に沿うように決めることで、上記の問題は発生しなくなります。
全クラスから ActiveRecord::Base を継承するクラスを抽出する方法
方法
constants = Object.constants.map{|name| Object.const_get(name)}
=> ["2.3.5", ApplicationController, OpenSSL, Rational, Signal, "i686-linux", Pre
ttyPrint, TSort, MonitorMixin, StringScanner::Error, Module, NKF, Socket, Except
... (省略)
constants.select{|c| c.class == Class and c < ActiveRecord::Base and !c.abstract_class?}
=> [Photo(id: integer, user_id: integer, file_name: string, created_at: datetime
), User(id: integer, email: string, created_at: datetime)]
問題
ロードされていないクラスを取得することができません。例えば、development モードで実行しているとき *1 はリクエストごとに Model クラスがキャッシュされないため、そのリクエストでアクセスされなかった Model クラスを取得することが出来ません。
対策
$RAILS_ROOT/app/models/ 以下の *.rb ファイルを事前に require すれば回避できます。
*1:正確には config.cache_classes = false が設定されているとき
トラックバック - http://d.hatena.ne.jp/benikujyaku/20100801/1280659924