gotoshin

主に学んだ事の自分メモ用です。記事に書くまでも無いような事はhttps://scrapbox.io/study-diary/に書いてます。

どうやらhelper_methodに指定したメソッドはviewだけでなくcontrollerでも使えるらしい

gihyo.jp

この本を写経している際にふと、これどういう仕組で呼ばれてるメソッドなんだろうと調べたのでついでにメモ。

まずAdmin::BaseControllerというクラスを用意しcurrent_administratorというhelper_methodを定義。

class Admin::BaseController < ApplicationController
  private def current_staff_member
    if session[:staff_member_id]
      @current_staff_member ||=
        StaffMember.find_by(id: session[:staff_member_id])
    end
  end

  helper_method :current_administrator

end

次にStaff::SessionControllerという子クラスを用意し、上記のAdmin::BaseControllerクラスを継承。

継承したクラス内で、親クラスで定義したcurrent_administratorというhelper_methodを呼び出している。

class Staff::SessionController < Staff::Base
  def new
    if current_staff_member
      current_staff_test
      redirect_to :staff_root
    else
      current_staff_test
      @form = Staff::LoginForm.new
      render action: "new"
    end
  end
・
・
・

これは継承したから呼び出せているのか、それともhelper_methodで定義しているから呼べているのか疑問に思った。

本やネット記事をみてみるとhelper_method はviewから呼び出す事が可能なメソッドという趣旨の説明はあるが、controller内で呼び出せると記載されている記事が見当たらなかった。

調べてみると親クラスのメソッドを子クラスで単純には呼び出せない様だ。

スーパークラスのメソッドを呼び出す - クラスの継承 - Ruby入門

試しに親クラス以下の行をコメントアウトしたら、、、

helper_method :current_staff_member

子クラスのcurrent_staff_memberを呼び出している部分でエラーが発生した。

また親クラスを以下の様に変更し呼び出したらcurrent_staff_testメソッドがきちんと呼び出された。

class Admin::BaseController < ApplicationController
  private def current_staff_member
    current_staff_test
    if session[:staff_member_id]
      @current_staff_member ||=
        StaffMember.find_by(id: session[:staff_member_id])
    end
  end

  private def current_staff_test
    p "テスト"
  end

  helper_method :current_staff_member, :current_staff_test

end

よって、helper_methodに定義する事でview側だけでなくcontroller内でも使用可能らしい。

ちなみにプライベートメソッドとして定義しなければ別にhelper_methodに指定とかしなくても呼び出し可能だった。

つまりhelper_methodはcontroller内で呼び出すために定義するのではなく、viewで使用する場合に定義するのがセオリーだと思われる。

class Staff::Base < ApplicationController
  private def current_staff_member
    current_staff_test
    if session[:staff_member_id]
      @current_staff_member ||=
        StaffMember.find_by(id: session[:staff_member_id])
    end
  end

  def current_staff_test
    p "テスト"
  end

  helper_method :current_staff_member

end

(参考) [メモ][Rails]コントローラーのメソッドをヘルパーとしてビューで使う - Qiita