記事を削除する: 小林研 Rails Tips (61)

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

https://github.com/hkob/hkob_blog

はじめに

Rails Tips の 60 回目です。昨日は、edit と update による記事の更新を行いました。次に記事を削除するに書かれている destroy を実装しましょう。

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

7.5 記事を削除する

こちらも先にテストを記述しましょう。destroy は基本的にエラー分岐はないので、オブジェクトが1減ることと、リダイレクトされることを確認します。以前、request_spec テンプレートの準備 : 小林研 Rails Tips (50) で示してテンプレートのレスポンスコードが間違ったままだったので、修正してあります。destroy は see_other にならないと Rails 7 からは事故になりかねないので、303 にする必要があります。まだ shared_example に登録されていないものはこちらで紹介してあります。

describe "DELETE #destroy" do
    subject { -> { delete article_path(object) } }
    let(:return_path) { articles_path }
    it_behaves_like "レスポンスコード確認", 303
    it_behaves_like "オブジェクトが1減るか?", Article
    it_behaves_like "リダイレクト確認"
    it_behaves_like "Notice メッセージ確認", "記事を削除しました。"
  end

昨日の before_action に destroy を追加します。以前はメソッドがなくても問題ありませんでしたが、7.1 からは厳格に存在するものしか書けなくなったためです。

before_action :take_one, only: %i[show edit update destroy]

残りは destroy の実装です。status: :see_other が重要なだけで、それ以外はほとんど問題ないと思います。

def destroy
    @article.destroy
    redirect_to articles_path, notice: notice_message(Article), status: :see_other
  end

これで destroyのテストおよび実装が完了しました。RSpec の結果は以下のようになっています。無事に全てのテストが通過しています。

DELETE #destroy
    behaves like レスポンスコード確認
      レスポンスのステータスが 303 であること
    behaves like オブジェクトが1減るか?
      Article.count が 1 つ減ること
    behaves like リダイレクト確認
      is expected to redirect to "/articles"
    behaves like Notice メッセージ確認
      notice に「記事を削除しました。」が出力されること

index へのリンク追加

昨日、edit のリンクを追加し忘れました。今回の削除のリンクとともに index.html.haml に追加します。共に制御列に並べて表示することにします。ここで、使っている destroy_lotfp およびその中で利用している confirm_destroy はこちらで紹介しています。

- 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
          = lotfp article_path(article)
          = lotfp edit_article_path(article)
          = destroy_lotfp article_path(article)
    %tr
      %td= lotfp new_article_path

さらに views/ja.yml の翻訳テキストも追加します。

ja:
  articles:
    index:
      title: 記事一覧
    show:
      title: 記事詳細
      link_title: 表示
    new:
      title: 記事作成
      link_title: 追加
    edit:
      title: 記事更新
      link_title: 編集
    destroy:
      link_title: 削除

  common:
    control: 制御
  confirm:
    destroy: "%{obj}を削除してよろしいですか?"

おわりに

ここまで実装しましたが、実際にサーバを起動してみると「削除」を押しても「表示」と同じ動作になってしまいました。そういえば JavaScript の設定を何も設定していないので、Turbo が発火していないはずです。明日は、JavaScript 周りの設定を実施し、「削除」リンクが動作するようにします。