表单提交后使用Carrierwave/Sidekiq显示上传到S3的图像

3
我正在使用Sidekiq、CarrierWave和CarrierWaveBackgrounder将我的图片上传到S3,这在后台工作方面效果很好。但是有一个问题:当我提交表单后,图片被排队到Sidekiq并进行处理,但页面重新加载的速度比后台作业快,导致上传的图片出现404错误。在另一次页面刷新后,图片通常会显示出来。
我想知道是否有办法显示临时文件(我在数据库中有一个image_tmp列,似乎存储了文件的路径,而文件正在处理/上传),或在处理完成后重新加载我的图片。
我可以轮询我的数据库以将“image_processing”更改为true,但这似乎有点浪费请求。
用户类的相关部分:
mount_uploader :profile_image, ProfileImageUploader

process_in_background :profile_image
store_in_background :profile_image

ProfileImageUploader包含Backgrounder

class ProfileImageUploader < CarrierWave::Uploader::Base

  include ::CarrierWave::Backgrounder::Delay
  include CarrierWave::MiniMagick

我的数据库有 profile_image_processingprofile_image_tmp 字段,当然还有一个 profile_image 列。
1个回答

1
我通过轮询image_processing属性来解决了这个问题。我的图像上传部分如下所示:
.form-group{ :class => (f.error field) ? "has-feedback has-error" : nil }
  = f.label field, :class => "col-md-3 control-label"

  .col-md-9
    = f.label field do
      = image_tag('ajax-loader.gif', class: 'image-loader hidden')
      - unless resource.image.blank?
        %p= image_tag(resource.image.thumb.url, data: { poll: resource.image_processing })
      - else
        %p No image uploaded yet.

      = f.input_field field, :as => :file
    %span.help-inline
      = f.error field, :class => "help-inline"

我随后使用以下CoffeeScript类钩入data-poll属性:

$ ->

  class ImagePoller

    constructor: (@$el) ->
      @$loader      = @$el.prev('.image-loader')
      @timer        = null
      @processing   = JSON.parse @$el.attr('data-poll')

      @resourcePath = "#{window.location.href}.json"

      @startPolling() if @processing

    startPolling: =>
      if @processing
        @toggleLoader()
        @$el.hide()
        @timer = setInterval =>
          promise = $.getJSON @resourcePath
          promise.done (data) =>
            @processing = data.image_processing
            @fetchImage(data.image.thumb.url) if not @processing
        , 100

    fetchImage: (image) ->
      clearInterval @timer
      @toggleLoader()
      @$el.attr 'src', image
      @$el.show()

    toggleLoader: ->
      @$loader.toggle()

  $('[data-poll]').each ->
    new ImagePoller $(@)

似乎就我的目的而言是正常工作的。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接