エンジニア歴は数カ月のひよっこですが、
現在、Railsを使ったアプリケーション開発にアサインしています。
これから仕事、趣味コードでハマったことを色々書いていったり、アウトプットしながらエンジニアとしてレベルアップしていきたいです。
やりたいこと
RailのHelperメソッド、非常に便利なんですが、Railsのデフォルトの挙動だと、app/helpers
以下のファイルに記載されたメソッドのスコープが、アプリケーションview全てになってしまうんですよね。
つまり、ビューのどこからでも使えてしまうという問題があります。
たとえば、現在日時のフォーマットを作りたいメソッドをいくつか作ったとして
app/views/students
(生徒) 以下のviewファイルでは
"2016/11/24" と表示したい
app/views/teachers
(先生) 以下のviewファイルでは
"16/11/24" と表示したいとする場合を考えます。
そこで、それぞれに対応するのヘルパーファイルを作って
view_today
メソッドでそれを実現したいとします。
module StudentsHelper
def view_today
Time.now.strftime("%Y/%m/%d")
end
end
module TeachersHelper
def view_today
Time.now.strftime("%y/%m/%d")
end
end
とした場合、helpersディレクトリ以下の view_today
メソッドが競合してしまう!
つまり、 生徒に関する画面表示で、"16/11/24" と表示されたり、逆に先生に関する画面表示で、"2016/11/24"と表示されたりしてしまいます。
そこで、helper methodを特定のviewに使いたいなーって思ったときに調べて解決策を見つけました。
具体的にどうやんの?
rails gem の githubではこのように書いてます。
config.action_controller.include_all_helpers
configures whether all view helpers are available everywhere or are scoped to the corresponding controller. If set tofalse
,UsersHelper
methods are only available for views rendered as part ofUsersController
. Iftrue
,UsersHelper
methods are available everywhere. The default configuration behavior (when this option is not explicitly set totrue
orfalse
) is that all view helpers are available to each controller.
簡単に訳すと、
`config/application.rb` ファイル内にある、
`config.action_controller.include_all_helper`の設定が
`true` になっていると、ヘルパーメソッドのスコープは全てのviewになります。
(Railsのデフォルト設定)
しかし、それを`false`に設定すると、例えば`UsersHelper`だと、
`UsersController`からrenderされたviewだけで利用可能になるよ。
これですね!
ではやってみましょう。
config.action_controller.include_all_helpers = false
としてあげると、先程と同じコードで
module StudentsHelper
def view_today
Time.now.strftime("%Y/%m/%d")
end
end
module TeachersHelper
def view_today
Time.now.strftime("%y/%m/%d")
end
end
StudentsController < ApplicationController
の index
やnew
画面等では確実に view_todayは "2016/11/24" になって、
TeachersController < ApplicationController
の indexやnew画面等では確実に view_todayは "16/11/24" になります。
名前空間にもつかえる
Hoges::ApplicationController < ApplicationController
Hoges::Foos::ApplicationController < Hoges::ApplicationController
のような形の名前空間を作った場合
app/views/hoges/foos
以下の viewファイルにだけ使えるヘルパーメソッドを定義したい!って場合には、
config.action_controller.include_all_helpers = false
とした上で、
module Hoges::Foos::ApplicationHelper
def view_today
Time.now.strftime("%d/%m/%y") #24/11/16 と表示される
end
end
とすればOKです。
この辺は、モデルに関するviewで使えるメソッドを定義できるdraperよりも柔軟的に対応ができるかなって思います。色々使い分けしたいですね!