コメント追加のテストと実装を記述する: 小林研 Rails Tips (68)

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

https://github.com/hkob/hkob_blog

はじめに

Rails Tips の 68 回目です。昨日の続きでコメント追加のテストと実装を追加します。

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

8.4 コントローラを生成する(テストと実装)

昨日作成した submit ボタンを押した時の create アクションをテストします。

require "rails_helper"

RSpec.describe Articles::CommentsController, type: :request do
  let!(:comment) { comments :can_delete }
  let!(:object) { comment }
  let!(:article) { object.article }
  let!(:attrs) { object.attributes }
  #    let(:not_mine) { comments :not_mine }

  let(:return_path) { article_path(article) }

  (中略)

  describe "POST #create" do
    before { object.destroy }
    subject { -> { post article_comments_path(article), params: {comment: attrs} } }
    context "正しいパラメータに対して" do
      it_behaves_like "レスポンスコード確認", 302
      it_behaves_like "オブジェクトが1増えるか?", Comment
      it_behaves_like "リダイレクト確認"
      it_behaves_like "Notice メッセージ確認", "コメントを登録しました。"
    end

    context "不正なパラメータに対して" do
      before { attrs["commenter"] = "" }
      it_behaves_like "レスポンスコード確認", 422
      it_behaves_like "オブジェクト数が変化しない?", Comment
      it_behaves_like "Alert メッセージ確認", "コメントの登録に失敗しました。"
    end
  end

articles/comments_controller.rb は以下のようになります。このコントローラでは、すべてのアクションで @article を取得する必要があるので、 take_base というメソッドを before_action で呼び出すようにしています。ここで使われている objects_from_params はここで説明しています。

class Articles::CommentsController < ApplicationController
  before_action :take_base

  def create
    @comment = @article.comments.build(comment_params)
    if @comment.save
      redirect_to @article, notice: notice_message(Comment)
    else
      flash.now[:alert] = alert_message Comment
      render "articles/show", status: :unprocessable_entity
    end
  end
  
  private

  def take_base
    @article = objects_from_params Article
  end

  def comment_params
    params.require(:comment).permit(:commenter, :body, :article_id)
  end
end

また、前回の article の時に追加すべきでしたが、notice や alert のメッセージを表示する場所を用意していませんでした。 application.html.haml の先頭に id をつけて登録しておきます。後で適切な CSS を設定するとよいと思います。

  %body
    #notice= notice
    #alert= alert
    - if @page_title.present?
      %h1= @page_title
    = yield

ここで commenter や body を空に設定したりすると、label の部分にエラーができるようになっています。それらを正しく入力するとコメントが追加されることがわかります。

おわりに

コメントの追加ができたので、明日はガイドでは実施していないコメントの編集や削除を実装してみましょう。