web-dev-qa-db-ja.com

Rails 5.2 Active Storageの添付ファイルの削除/削除

そのため、Active Storageを使用して、コレクションモデルに添付された複数の画像をアップロードしています。コレクションから単一の添付ファイルを削除または削除しようとする場合を除き、すべてが正常に機能します。

問題:何らかの理由で、コレクションの表示ページをロードするたびに、すべての画像がすぐにパージ/削除されます。もちろん、リンクをクリックするたびにファイルを削除したいだけです。誰もこの問題を解決する方法を知っていますか?

私のコレクションショービュー:

<div id="gallery">
  <% @collection.images.each do |image| %>
    <%= image_tag(image) %>
    <%= link_to 'Remove image', image.purge %>
  <% end %>
</div>

http://edgeguides.rubyonrails.org/active_storage_overview.html#removing-files のドキュメントを読みました(段落4を参照)

しかし悲しいことに、これは、purgeまたはpurge_laterメソッドを具体的に使用する方法に関する情報を提供しません。

[〜#〜] edit [〜#〜]現在、私のコードをこれに変更しました(残念ながらまだ機能しません):

<div id="gallery">
  <% @collection.images.each do |image| %>
    <%= image_tag(image) %>
    <%= link_to 'Remove', delete_image_attachment_collections_url(image.signed_id),
                method: :delete,
                data: { confirm: 'Are you sure?' } %>
    <% end %>
</div>

これで私のcollections_controller.rbに

  def delete_image_attachment
    @image = ActiveStorage::Blob.find_signed(params[:id])
    @image.purge
    redirect_to root_path
  end

添付画像を削除しようとした後、これは私にこのエラーを与えています:

Error I get when returning to the collection show after (trying to) delete an image.

サーバーログ:

Started DELETE "/collections/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaHBYdz09IiwiZXhwIjpudWxsLCJwdXIiOiJibG9iX2lkIn19--3e75276d414b4c2040e02cf0afbc083e2337faa0/delete_image_attachment" for ::1 at 2018-03-29 19:06:55 +0200
Processing by CollectionsController#delete_image_attachment as HTML
  Parameters: {"authenticity_token"=>"60zIkeknxRYp/sJIWNwF+BrEftYHSCQvak34h8FkadPXgVPQSXN/sCoxI/6FU+jZbqQitES81fyqkmIx6XYp6w==", "id"=>"eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaHBYdz09IiwiZXhwIjpudWxsLCJwdXIiOiJibG9iX2lkIn19--3e75276d414b4c2040e02cf0afbc083e2337faa0"}
  ActiveStorage::Blob Load (0.1ms)  SELECT  "active_storage_blobs".* FROM "active_storage_blobs" WHERE "active_storage_blobs"."id" = $1 LIMIT $2  [["id", 90], ["LIMIT", 1]]
  ↳ app/controllers/collections_controller.rb:69
  Disk Storage (0.1ms) Deleted file from key: 8wpzqPQcWYjK2rVEejcU88FB
  Disk Storage (0.0ms) Deleted files by key prefix: variants/8wpzqPQcWYjK2rVEejcU88FB/
   (0.0ms)  BEGIN
  ↳ app/controllers/collections_controller.rb:70
  ActiveStorage::Blob Destroy (0.2ms)  DELETE FROM "active_storage_blobs" WHERE "active_storage_blobs"."id" = $1  [["id", 90]]
  ↳ app/controllers/collections_controller.rb:70
   (2.0ms)  COMMIT
  ↳ app/controllers/collections_controller.rb:70
  ActiveStorage::Attachment Load (0.2ms)  SELECT  "active_storage_attachments".* FROM "active_storage_attachments" WHERE "active_storage_attachments"."record_id" = $1 AND "active_storage_attachments"."record_type" = $2 AND "active_storage_attachments"."name" = $3 LIMIT $4  [["record_id", 90], ["record_type", "ActiveStorage::Blob"], ["name", "preview_image"], ["LIMIT", 1]]
  ↳ app/controllers/collections_controller.rb:70
Redirected to http://localhost:3000/
Completed 302 Found in 5ms (ActiveRecord: 2.5ms)

rake routesの出力:

                            Prefix Verb   URI Pattern                                                                              Controller#Action
                              root GET    /                                                                                        home#index
                             about GET    /about(.:format)                                                                         pages#about
                           contact GET    /contact(.:format)                                                                       pages#contact
                          settings GET    /settings(.:format)                                                                  settings#edit
                       new_setting GET    /setting/new(.:format)                                                                   settings#new
                      edit_setting GET    /setting/edit(.:format)                                                                  settings#edit
                           setting GET    /setting(.:format)                                                                       settings#show
                                   PATCH  /setting(.:format)                                                                       settings#update
                                   PUT    /setting(.:format)                                                                       settings#update
                                   DELETE /setting(.:format)                                                                       settings#destroy
                                   POST   /setting(.:format)                                                                       settings#create
delete_image_attachment_collection DELETE /collections/:id/delete_image_attachment(.:format)                                       collections#delete_image_attachment
                       collections GET    /collections(.:format)                                                                   collections#index
                                   POST   /collections(.:format)                                                                   collections#create
                    new_collection GET    /collections/new(.:format)                                                               collections#new
                   edit_collection GET    /collections/:id/edit(.:format)                                                          collections#edit
                        collection GET    /collections/:id(.:format)                                                               collections#show
                                   PATCH  /collections/:id(.:format)                                                               collections#update
                                   PUT    /collections/:id(.:format)                                                               collections#update
                                   DELETE /collections/:id(.:format)                                                               collections#destroy
                Rails_service_blob GET    /Rails/active_storage/blobs/:signed_id/*filename(.:format)                               active_storage/blobs#show
         Rails_blob_representation GET    /Rails/active_storage/representations/:signed_blob_id/:variation_key/*filename(.:format) active_storage/representations#show
                Rails_disk_service GET    /Rails/active_storage/disk/:encoded_key/*filename(.:format)                              active_storage/disk#show
         update_Rails_disk_service PUT    /Rails/active_storage/disk/:encoded_token(.:format)                                      active_storage/disk#update
              Rails_direct_uploads POST   /Rails/active_storage/direct_uploads(.:format)                                           active_storage/direct_uploads#create

Routes.rb:

Rails.application.routes.draw do
  root 'home#index'

  get 'about', to: 'pages#about', as: :about
  get 'contact', to: 'pages#contact', as: :contact
  get 'instellingen', to: 'settings#edit'

  resource :setting
  resources :collections do
    member do
      delete :delete_image_attachment
    end
  end
end
12
royketelaar

イメージのコレクションをループし、各イメージでパージメソッドを呼び出しています。代わりに、コントローラーのdestroyメソッドにリンクする必要があります。以下のように、コントローラーのアクションを考慮し、ルート名を推測します。

エラーは、画像オブジェクトが完全なパスを返し、リンクがあなたが指したいものと考えているためです。代わりに、単にsigned_idそして、あなたのdelete_image_attachmentパス。

 <%= link_to 'Remove', delete_image_attachment_collections_url(image.signed_id),
                method: :delete,
                data: { confirm: 'Are you sure?' } %>

Destroyメソッドは次のようになります...

def delete_image_attachment
  @image = ActiveStorage::Blob.find_signed(params[:id])
  @image.purge
  redirect_to collections_url
end

ルートは次のようになります...

resources :collections do
  member do
    delete :delete_image_attachment
  end
end

レールルーティングガイド をご覧ください。

16
dbugger

さて、私は一種の私の問題を解決しましたが、何が起こっているのか本当に理解していません。

[削除]ボタンをクリックするたびに、次のエラーが表示されます。

ID 43のcollection_urlにリダイレクトしたいです(私のコレクションのIDは実際には6ですが、43はおそらく画像の添付ファイルのIDです)。

同じコレクションページを手動でリロードすると、画像は消えてしまいます(そのためうまくいきます)が、これは理想的なものではありません。

コントローラーのredirect_toがActivestorageイメージの添付IDではなく現在のコレクションIDを指すようにコードを改善する方法を誰かが知っていますか?

私のファイル

表示:collection/show.html.erb:

<div id="gallery">
  <% @collection.images.each do |image| %>
    <%= image_tag(image) %>
    <%= link_to 'Remove', delete_image_attachment_collection_url(image),
                    method: :delete,
                    data: { confirm: 'Are you sure?' } %>
  <% end %>
</div>

コントローラー:collections_controller.rb

class CollectionsController < ApplicationController
  before_action :set_collection, only: [:show, :edit, :update, :destroy]
  before_action :set_collections

  # GET /collections
  # GET /collections.json
  def index
  end

  # GET /collections/1
  # GET /collections/1.json
  def show
  end

  # GET /collections/new
  def new
    @collection = Collection.new
  end

  # GET /collections/1/edit
  def edit
  end

  # POST /collections
  # POST /collections.json
  def create
    @collection = Collection.new(collection_params)

    respond_to do |format|
      if @collection.save
        format.html { redirect_to @collection, notice: 'Fotocollectie is aangemaakt.' }
        format.json { render :show, status: :created, location: @collection }
      else
        format.html { render :new }
        format.json { render json: @collection.errors, status: :unprocessable_entity }
      end
    end

    # collection = Collection.create!(collection_params)
    # redirect_to collection
  end

  # PATCH/PUT /collections/1
  # PATCH/PUT /collections/1.json
  def update
    respond_to do |format|
      if @collection.update(collection_params)
        format.html { redirect_to @collection, notice: 'Fotocollectie is bijgewerkt.' }
        format.json { render :show, status: :ok, location: @collection }
      else
        format.html { render :edit }
        format.json { render json: @collection.errors, status: :unprocessable_entity }
      end
    end
  end

  # DELETE /collections/1
  # DELETE /collections/1.json
  def destroy
    @collection.destroy
    respond_to do |format|
      format.html { redirect_to collections_url, notice: 'Fotocollectie is verwijderd.' }
      format.json { head :no_content }
    end
  end

  def delete_image_attachment
    @image = ActiveStorage::Attachment.find(params[:id])
    @image.purge
    redirect_to @current_page
  end

  private
    # Use callbacks to share common setup or constraints between actions.
    def set_collection
      @collection = Collection.find(params[:id])
    end

    def set_collections
      @collections = Collection.all
    end

    # Never trust parameters from the scary internet, only allow the white list through.
    def collection_params
      params.require(:collection).permit(:title, :order, images: [])
    end
end

モデル:collection.rb

class Collection < ApplicationRecord
  has_many_attached :images
end

ルート:routes.rb

Rails.application.routes.draw do
  root 'home#index'

  get 'about', to: 'pages#about', as: :about
  get 'contact', to: 'pages#contact', as: :contact
  get 'settings', to: 'settings#edit'

  resource :setting

  resources :collections do
    member do
      delete :delete_image_attachment
    end
  end
end
4
royketelaar

Blob vs Attachmentに関する更新をありがとう!添付ファイルを削除した後、次のように由来するフォームにredirect_backします。

def remove_attachment
  attachment = ActiveStorage::Attachment.find(params[:id])
  attachment.purge # or use purge_later
  redirect_back(fallback_location: collections_path)
end

ページ全体をリロードするのに最適なソリューションではありませんが、機能します...

3
Max Weber

以下は私にとってはうまくいきませんでした。

def delete_image_attachment
  @image = ActiveStorage::Blob.find_signed(params[:id])
  @image.purge
  redirect_to collections_url
end

だから私がやったことは、添付ファイルを見つけてそれをパージしたことです。 purge_laterを実行できますが、これが推奨されます。

def delete_image_attachment
  @image = ActiveStorage::Blob.find_signed(params[:id])
  @image.attachments.first.purge
  redirect_to collections_url
end

これにより、添付ファイルとBLOBレコードの両方が削除されました。

0
Praveen KJ