以前、複数のモデルを横断したリストを作成するという記事を書いたのですが、文字列からクラスにアクセスすることでもう少しうまくできそうな方法を見つけたのでメモしておく。
目次
参考
文字からクラスにアクセスする方法
ズバリ、.safe_constantize
か.constantize
を使う。
名前から、ObjectSpace というすべてのオブジェクトの登録した空間から、同じ名称のオブジェクトを得ることができます。
例えば以前は 2 つのモデルを混ぜたリストを作るとき以下コントローラを作りました。
1 | class MixListsController < ApplicationController |
これを以下のように書き換えることができます。
1 | class MixListsController < ApplicationController |
このような使い方であれば、classs
(変数名が適当だなとは感じますが)にアクセスしたいクラス名を書き加えるだけで、モデルを横断したリストを作ることができます。
では、classs
に存在しないクラス名を書いてしまった場合は?
上記のままではエラーになるので、もう一段階書き換えます。
1 | class MixListsController < ApplicationController |
上記の場合、safe_constantize
を使用しています。classs
に存在しないクラス名Hoge
を指定しています。obj.present?
で、エラーチェックを行うことで、存在しないものが与えられた場合に対応できます。
ruby でもできるのか
constantize
とsafe_constantize
は、rails のActiveSupport::Inflector
が提供する機能です。
これを ruby でも使えないか試みます。
以下の方法でできました。
まず、activesupport
のインストールします。
1 | bundle init |
サンプルとして、sample.rb
を作ります。
1 | require 'active_support/all' |
sample.rb
はruby sample.rb
で実行します。
実行結果は以下の通りです。
1 | 田中 |
2 つのクラスをまたいで、中身にアクセスできました。
rails 及び active_support が ruby 自体を拡張している故に、便利なメソッドを ruby そのままでは使えないということがあるというのは、気を付けたいポイントでした。
ではでは。