当触发回调时,清除附件仅适用于 destroy 而不适用于 destroy_all 方法

问题描述 投票:0回答:1

在销毁带有附件的记录后,我无法清除存储在 S3 存储桶中的图像。我搜索了很久,但我无法弄清楚是什么导致了这个问题。

我的 Tour 型号有两种类型的附件:

cover_image
(单个)和
images
(多个)。

创作过程进展顺利。我使用 Rails 作为 API,发送带有表单数据的 POST 请求。在我的控制器中,我附加了这样的图像:

def create_tour
      if(@params[:tour_cover_image].present?)
        tour_images = @params.select{ |key, _| key.to_s.start_with?('tour_image-') }
        tour = Tour.new(@tour_params)
        tour.save!
        tour.cover_image.attach(
          io: File.open(@params[:tour_cover_image].tempfile),
          filename: @params[:tour_cover_image].original_filename,
          content_type: @params[:tour_cover_image].content_type,
          key: "public/tours/#{tour.id}/cover_image/#{SecureRandom.uuid}-#{@params[:tour_cover_image].original_filename}"
        )
        tour_images.each do |key, image|
          tour.images.attach(
            io: File.open(image.tempfile),
            filename: image.original_filename,
            content_type: image.content_type,
            key: "public/tours/#{tour.id}/images/#{SecureRandom.uuid}-#{image.original_filename}"
          )
        end
      else
        tour = Tour.new(@tour_params.except(:images, :cover_image))
        tour.save!
      end
      tour
    end

我还创建了一个 Rake 任务,通过销毁所有记录来清理我的开发数据库:

namespace :tours do
  desc "This will destroy all tours and their dependencies"
  task destroy_all: :environment do
    Tour.destroy_all
    puts "All tours and their dependencies have been destroyed"
  end
end

在我的 Tour 模型中,我添加了一个回调,以便在记录被销毁时清除 S3 中的所有图像:

class Tour < ApplicationRecord
  has_many :tour_vehicles_tours, dependent: :destroy
  has_many :tour_vehicles, through: :tour_vehicles_tours
  has_many :schedule_stop, dependent: :destroy
  belongs_to :user
  has_one_attached :cover_image
  has_many_attached :images

  before_destroy :purge_images

  def purge_images
    images.purge
    cover_image.purge
  end
end

问题来了:

  • 当我通过 Rake 任务运行

    Tour.destroy_all
    时,会触发
    purge_images
    回调,但只有
    cover_image
    会从 S3 中删除。图像不会被清除,并且
    images.attached?
    在回调中返回 false。

  • 但是,当我使用

    Tour.last.destroy
    手动销毁记录时,回调会按预期工作,并且 cover_image 和图像都会从 S3 中清除。

什么可能导致 destroy_all 和 destroy 之间出现这种不一致?

ruby-on-rails ruby amazon-s3 rails-activestorage
1个回答
0
投票

来自文档的您好https://apidock.com/rails/ActiveRecord/Relation/destroy_all它应该按预期工作。您可以尝试添加它并查看它记录的内容吗?

  def purge_images
    # Add error handling and logging
    begin
      if cover_image.attached?
        cover_image.purge
        Rails.logger.info "Successfully purged cover image for Tour #{id}"
      end

      if images.attached?
        images.purge
        Rails.logger.info "Successfully purged #{images.count} images for Tour #{id}"
      end
    rescue StandardError => e
      Rails.logger.error "Failed to purge images for Tour #{id}: #{e.message}"
      # Optionally re-raise the error if you want to halt the process
      # raise e
    end
  end

另一件事是你想要

after_destroy
回调而不是
before_destroy

after_destroy_commit :purge_images

您可以在此处找到完整的回调列表https://guides.rubyonrails.org/active_record_callbacks.html#destroy-callbacks

© www.soinside.com 2019 - 2024. All rights reserved.