Rails5「中級」チュートリアル(3-2)投稿機能: ヘルパー(翻訳)

概要

概要

原著者の許諾を得て翻訳・公開いたします。

Rails5中級チュートリアルはセットアップが短めで、RDBMSにはPostgreSQL、テストにはRSpecを用います。
原文が非常に長いので分割します。章ごとのリンクは順次追加します。

注意: Rails中級チュートリアルは、Ruby on Railsチュートリアル(https://railstutorial.jp/)(Railsチュートリアル)とは著者も対象読者も異なります。

目次

Rails「中級」チュートリアル(3-2)投稿機能: ヘルパー(翻訳)

前のセクションで_collapsible_elements.html.erbファイルを手がけていたときに、「Railsのビューはロジックを置く場所ではない」と書きました。プロジェクトのappディレクトリにhelpersというディレクトリがあるので、Railsのビューのロジックをこのhelperディレクトリに切り出すことにします。

app/views/pages

それでは最初のヘルパーを作りましょう。まず新しいGitブランチを切ってそのブランチに移動します。

git checkout -B helpers

helpersディレクトリに移動してnavigation_helper.rbファイルを作成します。

app/helpers/navigation_helper.rb

ヘルパーファイル内では、ヘルパーをモジュールとして定義します。navigation_helper.rbでモジュールを定義しましょう(Gist)。

# app/helpers/navigation_helper.rb
module NavigationHelper
end

Railsでは、デフォルトで「すべてのヘルパー」を「すべてのビュー」に読み込みます。別々のヘルパーファイルにあるメソッド名が衝突する可能性があるので、この動作は個人的には好きではありません。このデフォルトの動作をオーバーライドするには、config/application.rbファイルを開き、Applicationクラスの内側に以下の設定を追加します。

config.action_controller.include_all_helpers = false

これで、ヘルパーに対応するコントローラのビュー以外ではヘルパーが効かないようになります。つまり、PagesControllerというコントローラがあると、pages_helper.rbファイルにあるすべてのヘルパーはpagesディレクトリのファイルだけに効くようになります。

NavigationControllerはまだないので、NavigationHelperモジュールに書いたヘルパーメソッドはまったく利用できない状態です。ナビゲーションバーはWebサイト全体で使うので、ApplicationHelperの中でNavigationHelperモジュールをincludeすることで使えるようになります。ファイルの読み込みやincludeがよくわからない場合は、こちらの記事をご覧ください。

application_helper.rbnavigation_helper.rbファイルをrequireします。これで、navigation_helper.rbの内容にアクセスできるようになります。次に、includeメソッドを使ってNavigationHelperモジュールをApplicationHelperモジュールに導入しましょう。変更後のapplication_helper.rbは次のようになります(Gist)。

# helpers/application_helper.rb
require 'navigation_helper.rb'

module ApplicationHelper
  include NavigationHelper
end

これで、NavigationHelperにあるヘルパーメソッドをアプリ全体で使えるようになりました。

_collapsible_elements.html.erbファイルを開きます。

app/views/layouts/navigation/_collapsible_elements.html.erb

if/elseステートメントの内側のコードをパーシャルに切り出すことにします。navigationディレクトリの下にcollapsible_elementsディレクトリを作成します。

app/views/layouts/navigation/collapsible_elements

作成したディレクトリの下に、_signed_in_links.html.erbファイルと_non_signed_in_links.html.erbファイルを作成します。それでは、_collapsible_elements.html.erbファイルのif/elseステートメントをカットして、対応するパーシャルに貼り付けましょう。貼り付け後のパーシャルは以下のようになります(GistGist)。

<!-- layouts/navigation/collapsible_elements/_signed_in_links.html.erb -->
<li class="dropdown pc-menu">
  <a id="user-settings" class="dropdown-toggle" data-toggle="dropdown" href="#">
    <span id="user-name"><%= current_user.name %></span>
    <span class="caret"></span>
  </a>

  <ul class="dropdown-menu" role="menu">
    <li><%= link_to 'Edit Profile', edit_user_registration_path %></li>
    <li><%= link_to 'Log out', destroy_user_session_path, method: :delete %></li>
  </ul>
</li>

<li class="mobile-menu">
  <%= link_to 'Edit Profile', edit_user_registration_path %>
</li>
<li class="mobile-menu">
  <%= link_to 'Log out', destroy_user_session_path, method: :delete %>
</li>
<!--layouts/navigation/collapsible_elements/_non_signed_in_links.html.erb -->
<li ><%= link_to 'Login', login_path %></li>
<li ><%= link_to 'Signup', signup_path %></li>

続いて_collapsible_elements.html.erbファイルのif/elseステートメントをrenderメソッドに置き換え、引数にcollapsible_links_partial_pathヘルパーメソッドを指定します。置き換え後のファイルは次のようになります。

<!-- layouts/navigation/_collapsible_elements.html.erb -->
<!-- ナビゲーションリンク/フォームなどのコンテンツをここにまとめて表示をオンオフできるようにする -->
<div class="collapse navbar-collapse navbar-right" id="navbar-collapsible-content">
  <ul class="nav navbar-nav ">
    <%= render collapsible_links_partial_path %>
  </ul>
</div><!-- navbar-collapse -->

collapsible_links_partial_pathは、これからNavigationHelperに定義するメソッドです。navigation_helper.rbファイルを開きます。

app/helpers/navigation_helper.rb

このモジュールにメソッドを定義します。定義後のnavigation_helper.rbファイルは次のようになります(Gist)。

<!-- app/helpers/navigation_helper.rb -->
module NavigationHelper

  def collapsible_links_partial_path
    if user_signed_in?
      'layouts/navigation/collapsible_elements/signed_in_links'
    else
      'layouts/navigation/collapsible_elements/non_signed_in_links'
    end
  end

end

定義したメソッドは割りと素直なコードです。ユーザーがサインインしていれば対応するパーシャルのパスを返し、サインインしていなければもうひとつのパーシャルのパスを返します。

最初のヘルパーメソッドの作成と、ビューのロジックのヘルパーメソッドへの切り出しが終わりました。本チュートリアルでは、今後ビューファイルにロジックが出現するたびにこのようにロジックを切り出すことにします。こうすることでテストや管理がやりやすくなり、アプリがずっと簡単になります。

アプリの外観や機能は変わっていません。

変更をcommitします。

git add -A
git commit -m "Configure and create helpers

- Change include_all_helpers config to false
- Split the `_collapsible_elements.html.erb file's content into
  partials and extract logic from the file into partials"

helpersブランチをmasterブランチにmergeします。

git checkout master
git merge helpers

関連記事

新しいRailsフロントエンド開発(1)Asset PipelineからWebpackへ(翻訳)

デザインも頼めるシステム開発会社をお探しならBPS株式会社までどうぞ 開発エンジニア積極採用中です! Ruby on Rails の開発なら実績豊富なBPS

この記事の著者

hachi8833

Twitter: @hachi8833、GitHub: @hachi8833 コボラー、ITコンサル、ローカライズ業界、Rails開発を経てTechRachoの編集・記事作成を担当。 これまでにRuby on Rails チュートリアル第2版の監修および半分程度を翻訳、Railsガイドの初期翻訳ではほぼすべてを翻訳。その後も折に触れて更新翻訳中。 かと思うと、正規表現の粋を尽くした日本語エラーチェックサービス enno.jpを運営。 実は最近Go言語が好きで、Goで書かれたRubyライクなGoby言語のメンテナーでもある。 仕事に関係ないすっとこブログ「あけてくれ」は2000年頃から多少の中断をはさんで継続、現在はnote.muに移転。

hachi8833の書いた記事

夏のTechRachoフェア2019

週刊Railsウォッチ

インフラ

ActiveSupport探訪シリーズ