記事のリストを表示する: 小林研 Rails Tips (56)

このページの内容は以下のリポジトリに1日遅れで反映されます(記事執筆前に前日分をコミットしています)。

https://github.com/hkob/hkob_blog

はじめに

Rails Tips の 56 回目です。モデルのバリデーションのテストを先に記述したので、元に戻って記事のリストを表示する部分を実装します。

Rails をはじめよう - Railsガイド

6.4 記事のリストを表示する

Rails ガイドではいきなりコントローラを記述していますが、先にテストを修正しましょう。ページタイトルに「記事一覧」、テーブルのタイトル行に「タイトル」と表示することにします。それらが描画されていることを確認します。

  describe "GET #index" do
    subject { -> { get articles_path } }
    it_behaves_like "レスポンスコード確認", 200
    it_behaves_like "描画結果に文字列が含まれている?", %w[記事一覧 タイトル]
  end

まず、app/controllers/articles_controller.rb@articles を取得します。

  def index
    @articles = Article.all
  end

取得したコンテンツを app/views/articles/index.html.haml で描画します。

- content_for :title do
  - @page_title = t ".title"

%table
  %thead
    = labels Article, %w[title], add_control: true
  %tbody
    - @articles.each do |article|
      %tr
        %td= article.title
        %td

ここで利用している labels は labels ヘルパー : 小林研 Rails Tips (31) で紹介したものです。また、labels の中では別の t_ars ヘルパーも利用しています。こちらは、t_ars ヘルパー : 小林研 Rails Tips (30) で紹介しています。

保存してテストが実行されると、labels がないと言われるので、まずテストを spec/helpers/application_helper_spec.rb を書きます。まだファイルがないので、作成します。

touch spec/helpers/application_helper_spec.rb

テストは今回の Article に合わせて書き換えてみました。中で使っている t_ars も追加で記述しています。 単一メソッド呼び出し の shared example については、単一メソッド呼び出し shared_example: 小林研 Rails Tips (12) から先日作成した shared_example.rb に貼り付けます。もう一つの 単一メソッド呼び出し(キーワード引数あり) は labels のところで紹介しているので、こちらも同様に貼り付けしておきます。

require "rails_helper"

describe ApplicationHelper, type: :helper do
  subject { helper }

  describe "common test" do
    it_behaves_like "単一メソッド呼び出し" do
      let(:test_set) do
        {
          t_ars: [
            [Article], "記事",
            [Article, :title], "タイトル",
            [Article, :body], "本文",
            [Article, %i[title body]], %w[タイトル 本文],
          ]
        }
      end
    end

    it_behaves_like "単一メソッド呼び出し(キーワード引数あり)" do
      let(:test_set) do
        {
          labels: [
            [Article, %i[title body]], {}, "<tr><th>タイトル</th><th>本文</th></tr>",
            [Article, %i[title]], {add_control: true}, "<tr><th>タイトル</th><th>制御</th></tr>",
          ],
        }
      end
    end
  end
end

貼り付けが終わると、こちらでも labels がないというエラーになります。さらにリンク先から app/helpers/application_helper.rb に labels の実装を追加します。また、その前日の t_ars の実装も追加します。これでヘルパーに関する実行時エラーがなくなり、「記事一覧」の表示が正しくされていないというテストになります。これは先日の articles.index.title に対応する翻訳テキストを修正すればよいです。また、ついでに common.control の翻訳テキストも追加しておきます。

ja:
  articles:
    index:
      title: 記事一覧

  common:
    control: 制御

残りは、t_ars が利用するモデルのクラスと属性の翻訳テキストのみになります。こちらもまだファイルが存在していないので、ファイルを作成します。

$ mkdir -p config/locales/models
$ touch config/locales/models/ja.yml

Article に関するものはこれくらいでしょうか。

ja:
  activerecord:
    ### model 名
    models:
      article: 記事

    ### model の attribute 名
    attributes:
      article:
        title: タイトル
        body: 本文
        created_at: 作成日時
        updated_at: 更新日時

これでテストが全て通過しました。仕様はこんな感じになっています。

ApplicationHelper
  common test
    behaves like 単一メソッド呼び出し
        mst: t_ars
      上述のメソッドの結果が正しいこと
    behaves like 単一メソッド呼び出し(キーワード引数あり)
        mst: labels
      上述のメソッドの結果が正しいこと

Article
  属性に関する共通テスト
    behaves like 存在制約
      is expected to be valid
      title の内容が nil のとき、エラーになること
      body の内容が nil のとき、エラーになること
    behaves like 削除可能制約
      削除できること
    body length check
      body is 10 characters
        is expected to be valid
      body is 9 characters
        is expected to be invalid

ArticlesController
  GET #index
    behaves like レスポンスコード確認
      レスポンスのステータスが 200 であること
    behaves like 描画結果に文字列が含まれている?
      レスポンスの文字列が「["記事一覧", "タイトル"]」を含むこと

Finished in 0.09118 seconds (files took 1.22 seconds to load)
10 examples, 0 failures

おわりに

既存の記事で説明した実装は今回はリンクのみ紹介させていただき記述は省略させていただきました。詳しくは上に書いたリポジトリを参照してください。