質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Ruby on Rails 5

Ruby on Rails 5は、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

Ruby on Rails

Ruby on Railsは、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

jQuery

jQueryは、JavaScriptライブラリのひとつです。 簡単な記述で、JavaScriptコードを実行できるように設計されています。 2006年1月に、ジョン・レシグが発表しました。 jQueryは独特の記述法を用いており、機能のほとんどは「$関数」や「jQueryオブジェクト」のメソッドとして定義されています。

Docker

Dockerは、Docker社が開発したオープンソースのコンテナー管理ソフトウェアの1つです

Ajax

Ajaxとは、Webブラウザ内で搭載されているJavaScriptのHTTP通信機能を使って非同期通信を利用し、インターフェイスの構築などを行う技術の総称です。XMLドキュメントを指定したURLから読み込み、画面描画やユーザの操作などと並行してサーバと非同期に通信するWebアプリケーションを実現することができます。

Q&A

解決済

2回答

1974閲覧

特定の動作をしたときに2回目のajaxのレスポンスがcanceledされてしまう

iwonder

総合スコア5

Ruby on Rails 5

Ruby on Rails 5は、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

Ruby on Rails

Ruby on Railsは、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

jQuery

jQueryは、JavaScriptライブラリのひとつです。 簡単な記述で、JavaScriptコードを実行できるように設計されています。 2006年1月に、ジョン・レシグが発表しました。 jQueryは独特の記述法を用いており、機能のほとんどは「$関数」や「jQueryオブジェクト」のメソッドとして定義されています。

Docker

Dockerは、Docker社が開発したオープンソースのコンテナー管理ソフトウェアの1つです

Ajax

Ajaxとは、Webブラウザ内で搭載されているJavaScriptのHTTP通信機能を使って非同期通信を利用し、インターフェイスの構築などを行う技術の総称です。XMLドキュメントを指定したURLから読み込み、画面描画やユーザの操作などと並行してサーバと非同期に通信するWebアプリケーションを実現することができます。

0グッド

0クリップ

投稿2020/01/11 07:39

編集2020/01/11 08:39

状況

家計簿アプリをRuby on Railsで作成している初学者です。
アイテム登録と削除機能をjQueryのAjaxを利用して非同期処理で実装しました。
アイテム登録を非同期で作成したあとそのアイテムを非同期を削除しようとするとエラーが起こります。
単体での処理は問題なく動作をするので原因の特定が難しいです。

  • 削除→登録 ○
  • 削除のみ ○
  • 登録のみ ○
  • 登録→削除 ✕

希望の動作としては非同期で作成した後でも非同期で削除ができるようにさせたいです。

コード

  • ajax部分のjQueryコード

javascript

1$(function(){ 2 function buildHTML(item){ 3 let html = `<li data-delete-li="${item.id}"> 4 <p> 5 ${item.title} 6 </p> 7 <p> 8 ${item.link} 9 </p> 10 <p> 11 ${item.color} 12 </p> 13 <p> 14 ${item.price} 15 </p> 16 <p> 17 ${item.private} 18 </p> 19 <p> 20 ${item.period_long} 21 </p> 22 <p> 23 ${item.period_unit} 24 </p> 25 <p> 26 ${item.first_payment} 27 </p> 28 <p> 29 ${item.description} 30 </p> 31 <a class="edit_item" href="/users/${item.uid}/items/${item.id}/edit">編集</a> 32 <a class="delete_item" data-delete="${item.id}" rel="nofollow" data-method="delete" href="/users/${item.uid}/items/${item.id}">削除</a> 33 </li>` 34 return html; 35 } 36 37 // 作成時の非同期処理 38 $(document).on('submit', '#new_item', function(e){ 39 e.preventDefault(); 40 let formData = new FormData(this); 41 let url = $(this).attr('action'); 42 43 $.ajax({ 44 url: url, 45 type: "POST", 46 data: formData, 47 dataType: 'json', 48 processData: false, 49 contentType: false 50 }) 51 52 53 .done(function(data){ 54 let html = buildHTML(data); 55 $('#result').append(html); 56 $('#result').animate({ scrollTop: $("#result")[0].scrollHeight }, 1500); 57 }) 58 59 .fail(function(){ 60 alert('投稿に失敗しました'); 61 }) 62 63 .always(function () { 64 $('#new_item_btn').prop("disabled", false); 65 $('#new_item')[0].reset(); 66 }) 67 return false; 68 }) 69 70 // 削除時の非同期処理 71 $(document).on('click', '.delete_item', function(e){ 72 e.preventDefault(); 73 let url = $(this).attr('href'); 74 let delete_id = $(this)[0].dataset['delete']; 75 76 $.ajax({ 77 url: url, 78 type: 'DELETE', 79 headers: { 80 'Content-Type': 'application/json', 81 }, 82 data: JSON.stringify({delete_id: delete_id}), 83 dataType: 'json', 84 processData: false, 85 contentType: false 86 }) 87 88 .done(function(){ 89 $("li[data-delete-li=" + delete_id + "]").remove(); 90 }) 91 92 .fail(function(){ 93 alert('削除にに失敗しました'); 94 }) 95 return false; 96 }); 97});
  • Ruby on Railsでのコントローラ(アクションはajax部分のみに絞ってあります)

ruby

1class ItemsController < ApplicationController 2 before_action :set_item, only: [:edit, :update, :destroy] 3 4 def create 5 @item = Item.new(item_params) 6 if @item.save 7 respond_to do |format| 8 format.json 9 end 10 else 11 redirect_to root_path 12 end 13 end 14 15 def destroy 16 if @item.destroy 17 respond_to do |format| 18 format.json 19 end 20 else 21 redirect_to root_path 22 end 23 24 end 25 26private 27 28 def item_params 29 params.require(:item).permit(:title, :link, :color, :plan, :price, :private, 30 payment_attributes:[:id, :period_long, :period_unit, :first_payment, :pay_method, :description]).merge(user_id: current_user.id) 31 end 32 33 def set_item 34 @item = Item.find(params[:id]) 35 end 36end
  • 作成時に返すJsonファイル(jbuilderを使っています)

ruby

1json.id @item.id 2json.uid current_user.id 3json.title @item.title 4json.link @item.link 5json.color @item.color 6json.plan @item.plan 7json.price @item.price 8json.private @item.private 9json.period_long @item.payment.period_long 10json.period_unit @item.payment.period_unit 11json.first_payment @item.payment.first_payment 12json.description @item.payment.description
  • 削除時に返すJsonファイル

json

1{"status":"ok"}

エラーメッセージ

作成→削除に出るエラーメッセージです。

エラー時に検証ツールのNetworkに出ているエラー内容です

仮説

1.今はajaxが別れているがdeferredを用いて作成後の後に働くajaxとしても削除のajax処理を書かないといけないのではないか?
2.ajaxが2重送信として受け取られているためにRails側の自動推測でhtmlレスポンスに切り替わってしまっているのではないか?

環境

Mac OS 10.15
Ruby 2.5.1
Rails 5.2.4.1
Docker 19.03.5

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ソースコードはじっくり見ていないのですが、jQueryがきちんと動かないようだとまずturbolinksの影響を考えたほうがよいかと思います。
もしそれが原因だとすると下記のようにしてみてください。

jQuery

1jQuery(document).on('turbolinks:load', function(){ 2 #ここにコードを書く 3});

投稿2020/01/11 08:06

no1knows

総合スコア3365

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

iwonder

2020/01/11 08:17

ご回答ありがとうございます。 turbolinksはassetとviewのapplicationからも記述を消し、切ってあるので影響はまずないと考えています。
iwonder

2020/01/11 08:38

最初は似たようなものかなと思い、非同期後に追加される削除のDOMがイベントハンドラに登録されていないと考え、 $('.delete_item').on('click', function(e){... ↓ $(document).on('click', '.delete_item', function(e){... に変更したのですが今の結果となってます。 多分ですがjQuery側ではなくRails側での設定ではないかと疑っている次第です。
guest

0

自己解決

turbolinksを有効化し、コントローラを登録と削除を分けたところ期待していた動作を行うようになりました。

投稿2020/01/11 11:20

iwonder

総合スコア5

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

iwonder

2020/01/11 11:25

分けたコントローラを戻してみましたが同じく期待した動作をしました。 原因としては、turbolinksを切ったことか切り方がまずかったと推測されます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問