1
0

More than 3 years have passed since last update.

Rails コントローラのコンストラクタでは super を呼ぼう

Posted at

Ruby では他の言語におけるクラスのコンストラクタにあたる処理を initialize メソッドとして定義します。(initialize のリファレンス

Rails では典型的なコントローラを ApplicationController の派生クラスとしてつくります。そのため、コントローラの初期化を initialize で実装すると基底クラスの initialize をオーバーライドすることになります。(ApplicationController のリファレンス

リファレンスにあるとおり、ApplicationController は

Object
^
AbstractController::Base
^
ActionController::Metal
^
ActionController::Base
^
Rails::ApplicationController

という継承関係にあります(上に行くほど抽象的な親です)。このうちコントローラとしての初期化は主に ActionController::Metal#initialize で行われているようです。

したがって、initialize 内で super を呼ぶことで、基底クラスのコンストラクタを呼び出しつつも、独自の初期化処理をすることができます。(super のリファレンス

オーバーライドした基底クラスのメソッドを super で呼び出さないと、コントローラとして必要な処理が欠けてしまい、たとえばページが正常に表示されないといった不具合を招きます。

例えば、以下の例では TweetsController を初期化する際に、ツイートを埋め込むために必要な前処理をオブジェクトの初期化時に行っています。

require 'oembed'

class TweetsController < ApplicationController
    def initialize
        OEmbed::Providers.register(OEmbed::Providers::Twitter)
        OEmbed::Providers::Twitter.endpoint += "?omit_script=true"
        super // This is it
    end

    def show
        @tweet = Tweet.find(params[:id])
        @tweet_embedded = OEmbed::Providers.get(@tweet.url).html
    end
end

このように、 initialize 内で super によって基底クラスのオーバーライドしたメソッドを呼び出すことで、 Rails の設計に沿ったコントローラをつくることができます。


このように子クラスから親クラスのメソッドを呼び出すことは、コンストラクタに限らず設計次第ではよく行われ、その是非は別としても、言語機能としてはよくあります。たとえば C++ では super キーワードこそないものの、親クラス名を明示して AbstractClass::method() のようにメンバ関数を呼び出すことができます。(参考

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0