Railsでviews内でcontrollerのアクション名を取得したい

こんにちは!kossyです!




今回は、Railsでviews内でcontrollerのアクション名を取得する方法について、ブログに残してみたいと思います。



環境

Ruby 2.6.6
Rails 6.0.3
MacOS Catalina




action_nameメソッドを使う

views内でアクション名を取得したい場合は、action_nameメソッドを使えばOKです。

試しに適当なviewファイルにbinding.pryを仕込んで、リクエストを送ってみます。

#  indexアクションの場合

$ action_name
=> "index"

indexアクションだったので、"index"が返り値になりました。

ソースコードを読んでみよう

ついでなのでどのような内部実装なのか見に行ってみました。

# 前提: viewファイルにbinding.pryを仕込んでリクエストを送って、REPLを起動している

$ self.method(:action_name).source_location
=> ["/usr/local/bundle/gems/actionview-6.0.3.7/lib/action_view/helpers/controller_helper.rb", 16]

該当コードはこちら。

      CONTROLLER_DELEGATES = [:request_forgery_protection_token, :params,
        :session, :cookies, :response, :headers, :flash, :action_name,
        :controller_name, :controller_path]

      delegate(*CONTROLLER_DELEGATES, to: :controller)

github.com

controllerからdelegateされているみたいです。なのでcontrollerの定義元を見に行ってみます。

  class Base
    ##
    # Returns the body of the HTTP response sent by the controller.
    attr_internal :response_body

    ##
    # Returns the name of the action this controller is processing.
    attr_internal :action_name

github.com

attr_internalメソッドでaction_nameが定義されています。

attr_internalメソッドについては以下のブログで詳しく解説されていました。

blog.shitake4.tech

ユースケース

例えば部分テンプレートを使っている場合に、アクション名で処理を分岐したい時なんかに使えるかと思います。

# app/views/posts/_form.html.slim


- if action_name == 'new'
  '新規作成'
- else
  '編集'

また、renderメソッドに動的にアクション名を渡したい時にも使えるかなと。

render partial: action_name