以下のようにrailsコマンドでコントローラを生成しました。
$ rails rails generate controller admin/hoge
上記のとおり実行したら、
>class Admin::HogeController < ApplicationController
のようにデフォルトでは ApplicationController を継承するんですが、ApplicationControllerの部分に任意のクラスを指定しながら生成することはできますか?
Railsのバージョンは3.1.0です。
よろしくお願い致します。
目的がわからないので、なんともいえないですが。
Rubyは型で呼び出しの制限はしませんので、ApplicationController の持っているメソッド群を備えていれば任意のクラスを継承して使うことは原理的にはできます。
ただ、ApplicationController と同じ振る舞いをしないとちゃんと動かないので、あんまり意味がないですね。
ApplicationController 以外から継承するあり得るパターンとしては以下などがあります。
1. ApplicationController のサブクラスのサブクラスにする。
class AController < ApplicationController; end
class BController < AController; end
通常共通する処理はApplicationControllerに書きますが、
特定のコントローラ群では別の共通処理にしたい場合などにこうします。
2. ApplicationController の親クラスのサブクラスにする。
ApplicationController は、
AbstractController::Base ← ActionController::Metal ← ActionController::Base ← ApplicationController
という継承階層です。
例えば、Rack アプリとして動作させるなら ActionController::Metal のサブクラスでもいけます。
AbstractController::Base や ActionController::Base から直接継承することもできなくはないですが、必要なメソッドを再実装しなくてはなりません。
Rails のコントローラの仕組み自体をカスタマイズしたいのでなければ、
面倒なだけで意味がないですね。
詳しいご回答誠にありがとうございます。
目的としては、1の"特定のコントローラ群では別の共通処理にしたい場合"が近いです。
何がやりたいかというと、adminという名前空間にだけBASIC認証をかけたいと思っています。
そこで、ApplicationController のサブクラスであるAdminRootControllerというコントローラを作ってそこにBASIC認証処理を組み込み、名前空間adminのすべてのコントローラにこれを継承させれば要件が満たせるのではと思いました。
>|ruby|
class AdminRootController < ApplicationController
before_filter :auth
private
def auth
authenticate_or_request_with_http_basic do |user, pass|
user == 'username' && pass == 'password'
end
end
end
| >|ruby| class Admin::HogeController < AdminRootController end | それで、新しくコントローラを生成するときに、書き換えるのがめんどうなのでrailsコマンドで動的に生成するときにAdminRootControllerを指定できたら楽だなと思った次第です。 私にはこのような手法しか思い浮かばなかったですが、他にもっと合理的な方法があればご教示いただけましたら幸いです。