延迟作业以检查carrierwave_direct上传是否已完成并附加到模型

时间:2014-11-22 12:32:10

标签: carrierwave fog

我在用户上传的图片中使用了carrierwave_direct和delayed_job。这个过程是:

  1. 用户拖动&删除或选择一个文件。
  2. 使用carrierwave_direct直接将文件上传到S3,以执行所有表单签名等。
  3. 向用户显示一个用于裁剪其图像的对话框,该密钥(来自carrierwave_direct)通过隐藏字段传入。此时数据库中不存在记录,但文件存储在S3上。如果用户现在离开页面,我们将在S3上放置一个不属于任何模型的废弃/未附加文件。
  4. 如果用户完成此过程,将创建一条记录,并由工作队列完成处理(裁剪和创建多个缩略图版本)。
  5. 我必须在文件上传后立即将作业放入队列。它将延迟几个小时(或几天)。此作业检查文件是否存在,然后检查数据库中所有最近创建的图像记录,以查看是否有任何文件附加到该文件。如果没有,则删除该文件。

    最后,我想利用Carrierwave类来处理所有的雾,因为我还在使用它。

    我无法在任何地方找到它,所以这是我的版本。离开这里是为了让人们在将来遇到。

1 个答案:

答案 0 :(得分:0)

这就是我做到的。

def new
    # STEP 1: Show upload dialog that user can drop an image unto
    @image = current_user.portfolio.images.new.images

    # Status 201 returns an XML
    @image.success_action_status = "201"
end

def crop
    # STEP 2: A file is now on Amazon S3, but no record exists in the database yet. Make the user crop the image and enter a title.
    # Meanwhile, also setup a delayed job that will later check if this step has been completed.
    # Note: the crop view gets retrieved and inserted using ajax in images.js.coffee
    @image = Image.new(key: params[:key])
    Delayed::Job.enqueue ImageDeleteIfUnattachedJob.new(params[:key]), 0, 15.minute.from_now.getutc

    render :partial => "images/crop.html.erb", :object => @image
end

ImageDeleteIfUnattachedJob = Struct.new(:key) do
  def perform
    # Do any of the images created in the last week match the key that was passed in?
    # If not, the user probably went through the upload process, which then either went wrong or was cancelled.
    unless Image.where("created_at > ?", 1.week.ago).order('created_at DESC').any? { |image| key == image.images.path }

        # We spawn these to let Carrierwave handle the Fog stuff.
        @uploader = ImageUploader.new
        @storage = CarrierWave::Storage::Fog.new(@uploader)
        @file = CarrierWave::Storage::Fog::File.new(@uploader, @storage, key)
        if @file.exists?
            # Indeed, the file is still there. Destroy it.
            @file.delete
        else
            return true
        end
    end
  end

  def max_attempts
    3
  end
end