url_navi ヘルパー : 小林研 Rails Tips (37)

はじめに

Rails Tips の 37 回目です。今回は、ページの上に記載するパンくずリストを描画する url_navi ヘルパーです。

該当する application.html.haml

パンくずリストを各ページの先頭に記述してしまうと、noticealert などの下にパンくずリストが展開されてしまいます。そこで、パンくずリストの内容は各ページの :navi に相当する content_for の中に記載します。この部分は、以前ページタイトルを取得した時と同様に application.html.haml の中で yield によって呼び出します。もし、content_for が存在した時に、その yield の返り値を #navi id の下に展開します。

%body
    - cc = controller.class
    - finished = cc.finished?(action_name)
    = render "shared/top_link_bar", navi: @navi
    - if content_for?(:navi)
      #navi= yield :navi
    #notice{class: notice ? "notice" : ""}= notice
    #alert{class: alert ? "alert" : ""}= alert

各ページのトップには、以下のようにして今回解説する url_navi ヘルパーにパンくずリストの掲載するパスを配列で渡します。

- content_for :navi do
  - url_navi [teacher_jikanwaris_path, teacher_kurasu_shikens_path(@kurasu)]

url_navi の中身

excel や word での出力でない時(html出力の時)に shared/navi_link_bar を描画した結果を返します。

  # @param [Array<String, Array<String>>] array 「リンク文字列とパスの配列」または「パス」のどちらかを要素に持つ配列
  # @return [String] レンダリング結果
  def url_navi(array)
    render "shared/navi_link_bar", navi_data: array unless @excel_page || @word_page
  end

shared/_navi_link_bar.html.haml の中身

navi_link_bar の中身はこんな感じです。今回説明するつもりのない権限周りもそのまま掲載しておきます。現在のページを示すパスの最後だけは単に文字列が表示され、それ以前のものはリンクになります。リンクの文字列は基本的には locales から取得しますが、例外的に文字列も一緒に渡すとそちらを利用するようにしています。校務支援システムでは、パスからページ閲覧および編集権限が取得できるようにしているのでその辺りも描画されています。

:ruby
  navi_data ||= []
%ul
  - last = navi_data.last
  - navi_data.each_with_index do |path_or_array, i|
    %li= ">" unless i == 0
    - if path_or_array.is_a? Array
      - value, path = path_or_array
      - cap = controller_action_and_params(path)
    - else
      - path = path_or_array
      - cap = controller_action_and_params(path)
      - value = title_from_cap cap
    %li
      - if path_or_array == last
        = value
        - ps = privileges_str_from_cap cap
        - eps = @edit_privileges ? privileges_str(@edit_privileges) : nil
        - if eps && eps != ps
          = "(権限: #{ps}、編集権限: #{eps})"
        - elsif ps
          = "(権限: #{ps})"
      - else
        = link_to_lh value, path

おわりに

ページの先頭に url_navi ヘルパーを含んだ content_for を記述するだけで、各ページにパンくずリストを描画することができます。url_navi の引数は単にパスを記述するだけなので、非常に簡単です。仕組みは結構面倒くさいですが、一度作り込んでしまえば、毎回記述する部分はかなり短くなるのは Rails のいいところかなと思います。