Deviseを使った時に複数画像の削除機能が効かなくなったときにしたこと

<h2>はじめに</h2>

ユーザー情報編集画面を作成した時に、編集画面上で複数画像の削除ができる機能を実装しました。
その後Deviseを導入し、ユーザー情報編集画面をDeviseのRegistrations/edit.html.erbの方に置き換えた時に、この画像削除機能がうまく機能しなくなった時のお話です。
画像の操作はActiveStorageを使っています。

今回はこちらのアプリ上での削除機能の実装です。

Web URL: https://scouter.fun
GitHub URL: https://github.com/delicha/scouter

<h4>修正後</h4>


![Videotogif.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2730398/ba9bc974-bb3d-b789-53d2-af3af5816ae1.gif)


<h2>環境</h2>
macOS Big Sur(11.6.6)<br />
rails 6.1.6<br />
ActiveStorage 6.1.5.1

<h2>原因</h2>

複数画像の削除機能は以下のサイトを参考に作りました。
https://prograshi.com/framework/rails/active-storage/

```.tsx:models/user.rb
class User < ApplicationRecord
 （Devise導入後に追加した部分）
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :validatable
 （ここまで）
    ...

  has_one_attached :image
  has_many_attached :sub_images

  ...

end

```

```.tsx:users/edit.html.erb
<tr>
    <th><%= f.label :sub_images, 'サブ画像', class: "text-muted" %><br /><span class="small text-info">(サブ画像は3枚まで選択可)</span></th>
    <td>
      <%= f.file_field :sub_images, multiple: true, class: "form-control" %>
      <% if @user.sub_images.attached? %>
        　<div class="d-flex justify-content-start mt-2">
          　　<% @user.sub_images.each do |sub_image| %>
             <%= form.check_box :sub_image_ids, { multiple: true }, sub_image.id, false %>
            　　　<label for="user_sub_images_<%= sub_image.id %>">
              　　　<%= image_tag sub_image.variant(resize: "30x30"), class:'px-2 rounded-circle' %>
            　　　</label>
          　　<% end %>
          　　<p class="small">選択画像</p>
        　</div>
      <% else %>
        <span class="small">画像がありません。</span>
      <% end %>
    </td>
</tr>
```
上記で、ユーザー編集画面上で複数画像の選択と削除が実装できたのですが、Deviseを導入し、ユーザー編集画面をRegistrations/edit.html.erbに変更した後にこの機能が使えなくなってしまいました。

原因は、
<b><%= form.check_box :sub_image_ids, { multiple: true }, sub_image.id, false %>　</b>
のところでうまくsub_image_idsなどが渡せていないようでしたが、なぜそれがDevise（はじめて）の導入によって起こってしまったのかまではわかりませんでした。


<h2>結論</h2>

とりあえず、
<b><%= form.check_box :sub_image_ids, { multiple: true }, sub_image.id, false %>　</b>
は、Registrations/edit.html.erbから削除してユーザー情報編集画面上での削除を諦め、ユーザープロフィール画面上で画像を削除できるように仕様を変更。

以下のサイト（英語）を参考に、purgeメソッドを新たに作成して、画像を個別に削除できるように実装しました。

https://youtu.be/QcaSdsXtdvo

※以下詳しくはGithubの方をご覧ください。

```.tsx:attachments_controller.rb
class AttachmentsController < ApplicationController
  def purge
    attachement = ActiveStorage::Attachment.find(params[:id])
    attachement.purge
    redirect_back fallback_location: root_path, notice: "画像を削除しました。" 
  end
end

```
https://github.com/delicha/scouter/blob/scouter/app/controllers/attachments_controller.rb

```.tsx:users_controller.rb
class UsersController < ApplicationController
...

  def purge_image
    @user.image.purge
    redirect_back fallback_location: user_path(@user), notice: "画像は削除されました。"
  end
end
```
https://github.com/delicha/scouter/blob/scouter/app/controllers/users_controller.rb

```.tsx:routes.rb
delete "attachements/:id/purge", to: "attachments#purge", as: "purge_attachment"

```
https://github.com/delicha/scouter/blob/scouter/config/routes.rb

```.tsx:users/_sub_pic.html.erb
...

<% @user.sub_images.drop(1).each do |attachment| %>
  <div class="carousel-item">
     <%= image_tag attachment.variant(resize: "300x400"), class: 'rounded border mx-2 mb-3' %>
     <% if current_user.id == @user.id %>
        <p class="small">
           <%= link_to "▲画像削除", purge_attachment_path(attachment), class: "btn-light btn-sm rounded-pill", method: :delete,  data: { confirm: "「画像を削除します。よろしいですか？"} %>
        </p>
      <% end %>
  </div>
<% end %>

...

```
https://github.com/delicha/scouter/blob/scouter/app/views/users/_sub_pic.html.erb

実装した結果、以下のようになりました。

![Videotogif.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2730398/ba9bc974-bb3d-b789-53d2-af3af5816ae1.gif)

どなたかの参考になれば幸いです！

もし、Deviseを使った同じような状況でコードをこのように変更したらできるよ！というのがありましたら、ぜひ教えていただけたらうれしいです！

<h2>参考記事</h2>

https://prograshi.com/framework/rails/active-storage/
https://youtu.be/QcaSdsXtdvo
https://youtu.be/kNRU3CD0oc0