我使用Sidekiq和CarrierWave以及CarrierWaveBackgrounder在后台将我的图像上传到S3。除了一件事之外,这种方法很好:在我提交表单后,图像在Sidekiq中排队并进行处理,但页面重新加载比后台作业更快,导致上传图像上有404。在另一页刷新后,图像通常会显示出来。
我想知道是否有办法显示tmp文件(我的数据库中有一个image_tmp列,它似乎存储了文件的路径,当它处理/上传时) ,或在处理完成后重新加载我的图像。
我可以在我的数据库中轮询' image_processing'改为真,但这似乎有点浪费请求。
我的用户类的相关部分:
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_processing
和profile_image_tmp
的字段,当然还有profile_image
列。
答案 0 :(得分: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 $(@)
似乎可以为我的目的正常工作。