J'utilise donc Active Storage pour télécharger plusieurs images attachées à un modèle Collection. Tout fonctionne bien sauf lorsque j'essaie de purger/supprimer une seule pièce jointe d'une collection.
Le problème: Pour une raison quelconque, toutes mes images sont immédiatement purgées/supprimées chaque fois que je charge la page de démonstration d'une collection. Bien sûr, je veux seulement supprimer un fichier chaque fois que je clique sur le lien. Est-ce que quelqu'un sait comment résoudre ce problème?
Ma collection Voir la vue:
<div id="gallery">
<% @collection.images.each do |image| %>
<%= image_tag(image) %>
<%= link_to 'Remove image', image.purge %>
<% end %>
</div>
J'ai lu la documentation sur http://edgeguides.rubyonrails.org/active_storage_overview.html#removing-files (Voir paragraphe 4)
mais malheureusement, cela ne donne aucune information sur la manière d'utiliser spécifiquement la méthode purge ou purge_later.
EDIT Mon code a été changé pour ceci (qui ne fonctionne malheureusement toujours pas):
<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>
Avec cela dans collections_controller.rb
def delete_image_attachment
@image = ActiveStorage::Blob.find_signed(params[:id])
@image.purge
redirect_to root_path
end
Ce qui me donne cette erreur après avoir essayé de supprimer une image jointe:
Journal du serveur:
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)
Sortie de 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
Mes 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
Vous parcourez la collection d’images et appelez la méthode de purge pour chacune d’elles. Au lieu de cela, vous devriez créer un lien vers une méthode de destruction sur votre contrôleur, comme ci-dessous, en tenant compte des actions de votre contrôleur et en devinant les noms de votre route.
L'erreur est due au fait que l'objet image renvoie son chemin d'accès complet et que le lien indique ce que vous souhaitez indiquer. Au lieu de cela, vous voulez juste son signed_id
et que le lien appelle la route qui a votre chemin delete_image_attachment
.
<%= link_to 'Remove', delete_image_attachment_collections_url(image.signed_id),
method: :delete,
data: { confirm: 'Are you sure?' } %>
La méthode destroy ressemblerait à quelque chose comme ça ...
def delete_image_attachment
@image = ActiveStorage::Blob.find_signed(params[:id])
@image.purge
redirect_to collections_url
end
La route devrait être quelque chose comme si ...
resources :collections do
member do
delete :delete_image_attachment
end
end
Consultez le Guide de routage Rails pour plus de faits de routage amusants.
Merci pour votre mise à jour concernant Blob vs Attachment! Après avoir purgé la pièce jointe, je redirige vers le formulaire d'où je viens:
def remove_attachment
attachment = ActiveStorage::Attachment.find(params[:id])
attachment.purge # or use purge_later
redirect_back(fallback_location: collections_path)
end
Pas la meilleure solution pour recharger la page entière mais fonctionne ...
Okay en quelque sorte résolu mon problème mais je ne comprends pas vraiment ce qui se passe.
Chaque fois que je clique sur le bouton "Supprimer", le message d'erreur suivant s'affiche:
Il veut rediriger vers l'URL collection_url avec l'ID 43 (alors que l'ID de ma collection est en réalité 6, 43 est probablement l'ID de la pièce jointe de l'image).
Lorsque je recharge manuellement la même page de collection, la photo a disparu (donc cela fonctionne en quelque sorte), mais rien de tout cela n’est bien sûr idéal.
Est-ce que quelqu'un sait comment je peux améliorer mon code pour que le redirect_to de mon contrôleur pointe vers l'ID de collection actuel au lieu de l'ID de pièce jointe d'image Activestorage?
Voir: 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
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
Modèle: collection.rb
class Collection < ApplicationRecord
has_many_attached :images
end
Routes: 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