view
- Ajaxでタスクを削除するための作戦
⑴削除はサーバサイドでやる必要があるものの、今表示している一覧画面をそのまま表示し続けていたいため、Ajaxでサーバにリクエストを飛ばす
⑵削除された項目の非表示は、クライアントサイドにてJavaScriptで行う。
’⑴’の処理が無事行われたら非表示になるようにする
- ページ遷移ではなくAjaxリクエストを発生させる
remote: trueを記述
= link_to '', user, method: :delete, remote: true, data: { confirm: "ユーザ「#{user.name}」を削除します。よろしいですか?" }, class: 'far fa-trash-alt fa-lg'
controller
- destroyアクションをAjax向けに変更する
具体的には、リダイレクトをなくし、ステータスコード(204)だけ返すようにする。
※HTTP のレスポンスコード 204 No Content は、リクエストが成功した事を示します
def destroy
@user.destroy
head :no_content
# redirect_to users_url, notice: "ユーザ「#{@user.name}」を削除しました"
end
RailsのHTTPステータスのシンボル表現まとめ
https://blog.toshimaru.net/rails-http-status-symbols/
javaScript
[記載場所]
- 通常(v6.0のデフォルトはWebpackerになっている)
app/javascript/packs 配下のファイル
app/assets/javascripts/xxxxx.js
RailsGuide(v6.0)
https://railsguides.jp/asset_pipeline.html
※アセットパイプラインはassetsフォルダ内の各ファイルを最終的に一つのファイルに連結・圧縮する)
アセットパイプラインのパスを変える場合は、config/initializers/assets.rb内を変更する
-
組み込みrubyを使う場合
app/views/[controller名]/xxxxx.js.erb
※js.erbファイルでないと、<%= user.name %>などの記述は読み込めない -
Webpackerを使う
app/javascript/packs配下
※Webpackerでバンドルされたファイルは public/packs 配下にコピーされる。
(バンドルする対象のファイルは app/javascript 配下のファイル)
バンドルする単位をエントリーポイントと呼び、エントリーポイントとなるファイルは app/javascript/packs 配下のファイルです。
CSS,javaScript のどちらも app/javascript/packs 配下に配置することでエントリーポイントとすることが出来る。
※エントリーポイントとなるファイルに javaScript は import, CSS は @import を記載ればそれらがエントリーポイントのファイル名としてバンドルされる。
- 削除した対象を非表示にする
Ajaxは非同期通信です。
そのため、削除が成功したことを確認してから非表示にするためには、「削除処理が成功した」というイベントのハンドラの中に、対象を非表示にする処理を記述します。
rails-ujsは、remote: trueをつけたa要素に対して、Ajax通信が成功した時に、ajax:successというイベントを発行してくれます。
そこで、これに対応するイベントハンドラを記述します。
イベントハンドラを追加するにあたっては、対象となるa要素を簡単に特定できるようにしたいので、まずは、次のように削除リンクのa要素に「delete」という独自のCSSクラスを目印として付与してみます。
= link_to '', user, method: :delete, remote: true, data: { confirm: "ユーザ「#{user.name}」を削除します。よろしいですか?" }, class: 'far fa-trash-alt fa-lg delete'
- この目印を利用して、削除リンク(a要素)にイベントハンドラを設定します。
※ここでは、Turbolinksを利用しているため、windows.onloadを利用していない
document.addEventListener('turbolinks:load', function() {
document.querySelectorAll('.delete').forEach(function (a) {
a.addEventListener('ajax:success', function() {
var td = a.parentNode;
var tr = td.parentNode;
tr.style.display = 'none';
});
})
});
- 確認方法
・javaScriptのDOM要素はデベロッパーツールのコンソールでタグを堀々して確認してから実装しましょう。非表示対象を見つけたら、style.display = 'none' にしてみましょう。
・javaScriptが正常動作しない場合は、
デベロッパーツールのブレークポイントでどこまでコードを読めているか?を見ましょう。
・Ajax通信についても、通信が正常にできているかはデベロッパーツールで確認する事ができます。
期待するNetworkXHRでステータスが返ってきているかを見ましょう
・フロントエンドだけでなくバックエンドまで確認しましょう。
うまくいかない場合は、登場人物を明確にしてデータの受け渡しフローのどこでつまづいているのか?を切り分けましょう。
備考
techRacho
Rails 6: Webpacker+Yarn+Sprocketsを十分理解してJavaScriptを書く: 前編(翻訳)
https://techracho.bpsinc.jp/hachi8833/2020_01_16/85940