このページの内容は以下のリポジトリに1日遅れで反映されます(記事執筆前に前日分をコミットしています)。
https://github.com/hkob/hkob_blog
はじめに
Rails Tips の 60 回目です。昨日は、edit と update による記事の更新を行いました。次に記事を削除するに書かれている destroy を実装しましょう。
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
はこちらで紹介しています。
- destroy_lotfp ヘルパー : 小林研 Rails Tips (39): application_helper.rb に記載
- confirm_destroy_message: 小林研 Rails Tips (18): application_controller.rb に記載
- 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 周りの設定を実施し、「削除」リンクが動作するようにします。