Tech Racho エンジニアの「?」を「!」に。
  • 開発

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へ(翻訳)


CONTACT

TechRachoでは、パートナーシップをご検討いただける方からの
ご連絡をお待ちしております。ぜひお気軽にご意見・ご相談ください。