Ruby on Rails についてお聞きします。

以下のようにrailsコマンドでコントローラを生成しました。

$ rails rails generate controller admin/hoge

上記のとおり実行したら、

>class Admin::HogeController < ApplicationController

のようにデフォルトでは ApplicationController を継承するんですが、ApplicationControllerの部分に任意のクラスを指定しながら生成することはできますか?

Railsのバージョンは3.1.0です。
よろしくお願い致します。

回答の条件
  • 1人3回まで
  • 登録:
  • 終了:2011/09/17 12:47:03
※ 有料アンケート・ポイント付き質問機能は2023年2月28日に終了しました。

回答1件)

id:nuna No.1

回答回数32ベストアンサー獲得回数11

ポイント100pt

目的がわからないので、なんともいえないですが。

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 のコントローラの仕組み自体をカスタマイズしたいのでなければ、

面倒なだけで意味がないですね。

id:hardboiled243

詳しいご回答誠にありがとうございます。

目的としては、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を指定できたら楽だなと思った次第です。 私にはこのような手法しか思い浮かばなかったですが、他にもっと合理的な方法があればご教示いただけましたら幸いです。
2011/09/12 18:47:53
  • id:nuna
    >ApplicationController のサブクラスであるAdminRootControllerというコントローラを作ってそこにBASIC認証処理を組み込み、名前空間adminのすべてのコントローラにこれを継承させれば要件が満たせるのではと思いました。

    そうですね。可能だと思います。
    Rails的にはpluginを作って
    class Admin::HogeController < ApplicationController
    basic_auth_required
    end
    class Admin::FugaController < ApplicationController
    basic_auth_required
    end
    などと宣言的に書くのが主流ですが、サブクラスにするのでもいいと思います。

    >新しくコントローラを生成するときに、書き換えるのがめんどうなのでrailsコマンドで動的に生成するときにAdminRootControllerを指定できたら楽だなと思った次第です。

    generator plugin というのを作れば、
    $ rails generate basic_auth_controller admin/hoge
    のようにして生成できますが、plugin 作るほうが面倒ですね……
    複数人開発で間違いが起きにくいようにというのであればメリットもありますが。

この質問への反応(ブックマークコメント)

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

回答リクエストを送信したユーザーはいません