[Rails]DELETEリンクでpreventDefaultが効かない

### 環境
ruby 2.6.5
Rails 6.0.4.1
[sweetalert2](https://sweetalert2.github.io/#configuration)(CDN)

### 実装したい機能
削除ボタンを押すと、ブラウザに警告アラートを出す。
OKを押すと削除され、Cancelを押すと、元の画面に戻る。

イメージ↓
![cation.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2257482/64d5c09d-943f-df06-f2e7-fbffaad5208e.png)


### 実装方法
削除リンク要素をgetElementByIdで取得。
クリックイベント内でpreventDefaultを使用し、削除イベントを中止。
sweetalert2を使用して、警告アラートを表示。
OKが押された場合のみ、削除処理を進める。

### 生じた問題
Railsのヘルパーメソッドであるlink_toで削除リンクを実装した場合、
JavascriptのpreventDefaultメソッドが効かず、
コントローラー処理が呼び出されてしまう。
→[解決策へ飛ぶ](#解決策)

### 原因特定までの経緯
JSにdebugger、Railsコントローラー側にbinding.pryを記述し動かすと、
binding.pryも発動した。
コントローラーにリクエストが届いてしまっている。
つまり、イベントがキャンセルできていないと考えた。

**ビューファイル抜粋**

```
<td>
　　<%= link_to '削除', user_xxx_path(@user, xxx), method: :delete, id: "test" %>
</td>
```
**コントローラー処理抜粋**

```
  def destroy
    binding.pry
    @xxx = Xxx.find_by(id: params[:id])    
    redirect_to user_path(current_user) if @xxx.destroy
  end
```

**JSファイル**

```
function cation() {
  //削除要素の取得
  const test = document.getElementById("test");
  // 削除ボタン押下でイベント発火
  test.addEventListener('click',(e) => {
    console.log("イベント読み込みok");
    console.log(e.cancelable);
    e.preventDefault();
    debugger;
    
  // 削除警告画面
    Swal.fire({
      title: '◯◯◯を削除します',
      html: '過去の△△△も削除され、元に戻せません。',
      footer: '<a href="#" class="text-blue-400 hover:bg-gray-200">◯◯◯の解約はこちら</a>',
      icon: 'warning',
      showCancelButton: true,
      confirmButtonColor: '#3085d6',
      cancelButtonColor: '#d33',
      confirmButtonText: 'OK',
      allowOutsideClick: false,
    }).then((result) => {
      if (result.isConfirmed) {
        Swal.fire(
          '削除しました',
          'Your file has been deleted.',
          'success'
        )};
    });
  });
};

window.addEventListener('load', cation);
```

また、下記についても確認がとれた。

・要素選択、イベント発火に問題はない
→console.log("イベント読み込みok")で、イベントの読み込みは確認できた。

・　aタグのリンク遷移はキャンセル可能なイベントである
→console.log(e.cancelable)の結果がtrueであった。

以上から、ヘルパーメソッド(link_to)に
オプションでメソッド(method: :delete)を指定しているのが
原因ではないかと考えた。


それを検証するために、メソッドオプションを指定しない編集リンクを作成した。

**追加検証：ビュー抜粋**

```
<%# ↓編集リンク追加 %>
<td>
　　<%= 編集', edit_user_subscription_path(@user, subs), id: "test-b", %>
</td>
<%# ↑編集リンク追加 %>
<td>
　　<%= link_to '削除', user_xxx_path(@user, xxx), method: :delete, id: "test" %>
</td>
```

**追加検証：該当コントローラー**

```
  def edit
    binding.pry
    @xxx = Xxx.find_by(id: params[:id])    
  end
```

**JSファイル**
要素をtestからtest-bに変更

```
function cation() {
  //削除要素の取得
  const test-b = document.getElementById("test-b");
  // 削除ボタン押下でイベント発火
  test-b.addEventListener('click',(e) => {
    console.log("イベント読み込みok");
    console.log(e.cancelable);
    e.preventDefault();
    debugger;
    ~以下、略〜
```

これで編集リンクをクリックすると、
debuggerのみ動作し、binding.pryは動作しなかった。
コントローラーが動いていないことから、イベントが中止できたと判断した。

念の為、削除要素の(method: :delete)を消して同様のテストをしたところ、
編集リンクと同様の挙動となった。

つまり、ヘルパーメソッド(link_to)のオプション、
メソッドの指定(method: :delete)が原因だと特定できた。

また、ヘルパーメソッドを使用せずaタグで試したが同様の結果であった。

```
<a id="test-b" data-method="delete" href=<%= user_subscription_path(@user, xxx) %> >削除</a>
````


### 解決策
formを作り、a要素をinput要素(submit)に変更。
コントローラーのbinding.pryが動作せず、
JS側のdebuggerのみ動作することを確認。
無事イベントを中止にできた。

```
<%= form_with url: user_xxx_path(@user, xxx), method: :delete, local: true do |f| %>
  <%= f.submit '削除', id: "test" %>
<% end %>
```
かなり古い2次情報記事だが、こちらを参考に上記方法を検証した。
→[teratail](https://teratail.com/questions/38758)

### 感想
MDN(addEventListener, preventDefault, a)、
Railsドキュメント(link_to)等を確認し、
オプションなどを試してみたがうまく行かなった。

また、そもそも一次情報に書かれいていることをを理解できなかった。

問題が解決できたこと、
またその結果実装を進められる結果は、良いが、
解決方法とそこまでの過程が課題アリだなと感じた。

具体的には、「イベントオブジェクト」について理解を深める必要がある。
簡易アクションとして、[MDN](https://developer.mozilla.org/ja/docs/Learn/JavaScript/Building_blocks/Events)でイベント入門を確認。
アプリ実装後、もっと詳しく見ていきたい。

＊＊＊
オリアプ実装していると、「ちゃんと理解できていない」がよくわかる。
カリキュラム学習では、わかった！と思い、
課題実装でスムーズに実装できていても、
「自由に使いこなす」には至らないことを痛感する。

もっと理解したいポジティブな感情と同時に、
今、自力で答えを見つけられないくやしやだったり、
実装を優先するため、一時保留にする不安や焦りもわいてくる。

後者は、ネガティブな感情ではあるが、
何かに取り組み、対峙している結果とも捉えられる。

まだスタートラインにも立ってないし、
課題も改善も山積みだが、
今は、取り組み続けることにフォーカスしようと思った。

まずは、オリアプを完成させる！