简体   繁体   English

Rails 5.2 Active Storage 清除/删除附件

[英]Rails 5.2 Active Storage purging/deleting attachments

So I'm using Active Storage to upload multiple images attached to a Collection model.所以我使用 Active Storage 上传附加到 Collection 模型的多个图像。 Everything works well except whenever I'm trying to purge/delete a single attachment from a collection.一切正常,除非我试图从集合中清除/删除单个附件。

The problem: For some reason all my images immediately get purged/deleted whenever I load the show page of a collection.问题:出于某种原因,每当我加载集合的显示页面时,我的所有图像都会立即被清除/删除。 Of course I only want to delete a file whenever I click the link.当然,我只想在单击链接时删除文件。 Does anyone know how to solve this problem?有谁知道如何解决这个问题?

My collection show view:我的收藏展示视图:

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

I've read documentation on http://edgeguides.rubyonrails.org/active_storage_overview.html#removing-files (see paragraph 4)我已阅读有关http://edgeguides.rubyonrails.org/active_storage_overview.html#removing-files 的文档(参见第 4 段)

but sadly this doesn't give any information on how to specifically use the purge or purge_later method.但遗憾的是,这并没有提供有关如何专门使用 purge 或 purge_later 方法的任何信息。

EDIT Currently changed my code to this (which still sadly doesn't work):编辑目前将我的代码更改为此(遗憾的是仍然不起作用):

<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>

With this in my collections_controller.rb在我的 collections_controller.rb 中有这个

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

Which is giving me this error after I tried to delete an attached image:在我尝试删除附加图像后,这给了我这个错误:

在(尝试)删除图像后返回收藏集时出现错误。

Server log:服务器日志:

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)

Output of rake routes : 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

My routes.rb:我的路线.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

You are looping through the collection of images and calling the purge method on each one.您正在遍历图像集合并在每个图像上调用清除方法。 Instead you should be linking to a destroy method on your controller, something like the below taking into account your controller actions and guessing at your route names.相反,您应该链接到控制器上的 destroy 方法,如下所示,考虑到您的控制器操作并猜测您的路由名称。

The error is because image object returns its full path and the link thinks that what you want to point to.错误是因为图像对象返回其完整路径并且链接认为您想要指向的内容。 Instead you just want its signed_id and want the link to call the route that has your delete_image_attachment path.相反,您只需要它的signed_id并希望链接调用具有您的delete_image_attachment路径的路由。

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

The destroy method would look something like this... destroy 方法看起来像这样......

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

The route should be something like so...路线应该是这样的……

resources :collections do
  member do
    delete :delete_image_attachment
  end
end

Check out the rails routing guide for more fun routing facts.查看rails 路由指南了解更多有趣的路由事实。

The following didn't work for me.以下对我不起作用。

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

So what i did is found the attachment and purged it.所以我所做的是找到附件并清除它。 You can do purge_later which is recommended.您可以执行purge_later ,这是推荐的。

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

This removed both attachment and blob record.这删除了附件和 blob 记录。

Thanks for your update regarding Blob vs Attachment!感谢您提供有关 Blob 与附件的更新! After purging the attachment I redirect_back to the form I came from like this:清除附件后,我将重定向返回到我来自的表单,如下所示:

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

Not the best solution to reload the entire page but works ...不是重新加载整个页面的最佳解决方案,但有效......

Okay I sort of solved my problem but I don't really understand what's happening.好吧,我有点解决了我的问题,但我真的不明白发生了什么。

Whenever I click on the "Remove" button I get this error:每当我单击“删除”按钮时,都会出现此错误:

It wants to redirect to the collection_url with ID 43 (while the ID of my collection is actually 6, 43 is probably the ID of the image attachment).它想重定向到 ID 为 43 的 collection_url(而我的集合的 ID 实际上是 6,43 可能是图像附件的 ID)。

When I reload the same collection page manually, the picture is gone (so it sort of works) but nothing of this is ofcourse ideal.当我手动重新加载相同的收藏页面时,图片消失了(所以它有点工作)但是这当然不是理想的。

Does someone know how I can improve my code so that the redirect_to in my controller points to the current collection ID instead of the Activestorage image attachment ID?有人知道如何改进我的代码,以便控制器中的 redirect_to 指向当前集合 ID 而不是 Activestorage 图像附件 ID?

My files我的文件

View: collection/show.html.erb:查看: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>

Controller: collections_controller.rb控制器: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

Model: collection.rb型号:collection.rb

class Collection < ApplicationRecord
  has_many_attached :images
end

Routes: routes.rb路线: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

If you arrived here looking for a way to delete an attachment via the rails console :如果您来到这里寻找通过 rails 控制台删除附件的方法:

user.image.purge

Source: https://edgeguides.rubyonrails.org/active_storage_overview.html#removing-files来源: https : //edgeguides.rubyonrails.org/active_storage_overview.html#removing-files

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM