Paperclip4&关于CREATE + UPDATE操作的Rails4后台作业

时间:2014-10-03 19:18:10

标签: ruby-on-rails-4 paperclip background-process resque

我正在尝试如何使用回形针与后台工作,特别是在更新时。

我想要的是:2步更新第1次分配原始图片,第2次在后台工作中生成样式

更新用户参数时:

  
      
  • 我在S3上有一个文件(使用direct_upload上传)
  •   
  • 在回形针执行过程之前,我将此文件(url)附加到我的document.attachment模型
  •   
  • Paperclip使用url并生成原始文件(将文件复制到paperclip文件夹)   
        
    • 不要处理样式
    •   
  •   
  • 一旦原件正常,我想重新处理其他样式(:medium,:thumb)
  •   
  • 隔离后台作业(Resque)中的重新处理(或全局进程)以提高效率)
  •   

我做了什么

  
      
  • 从S3网址成功分配文件,所以我不会在这里详细说明   
        
    • 所有样式均来自S3 one
    •   
  •   
  • 阻止回形针post_process
  •   
  • 添加重新处理后台作业调用,如果@ user.save生成所有样式,然后使用@ user.panorama.attachment.reprocess重新处理所有样式,请在控制器之后调用控制器!...
  •   

我失败的地方

  
      
  • 更新操作上的样式重新处理隔离(后台作业)没有成功:   
        
    • 无限循环,因为自文件更改后,paperclip在重新处理后重新启动更新
    •   
  •   
  • 尝试使用模型和控制器方式,使用布尔“进程”但仍然在循环中使用
  •   
after_update :reprocess_styles
before_post_process :stop_process

    def stop_process
      false #stop paperclip styles the post processing
    end

    def reprocess_styles
      self.reprocess! :medium, :thumb #lauch the post process
      self.save(validate: false)
    end

事实上,它的更新操作会让我进入一个无法正常管理的循环。

我要么有一个无限循环再次重新处理样式,要么根本没有样式。

非常感谢您的帮助。

MODEL

class Panorama < Document
  attr_reader :attachement_remote_url
  before_create :attachment_remote_url
  before_update :attachment_remote_url

  # after_create :process_styles
  after_update :process_styles

  has_attached_file :attachment,
  styles: { medium: "1000x1000#", thumb: "160x160#" },
  convert_options: { medium: "-quality 75 -strip",
                     thumb: "-quality 75 -strip" },
  default_url: ":parent_type/:class/:style/missing.png",
  path: "/documents/:parent_type/:id_partition/:class/:style/:basename.:extension"

  validates_attachment :attachment,
  content_type: { content_type: ["image/gif", "image/png", "image/jpg", "image/jpeg"] },
  size: { less_than: 10.megabyte }

  before_post_process :stop_process

  def stop_process
    if !self.process && self.attachment_changed?
      # self.process = true #loop...
      false
    end
  end

  def attachment_remote_url
    self.attachment = URI.parse("path to my Amazon S3 file")
  end

  def process_styles
    if !self.process
      puts self.inspect
      # self.process = false #loop...
      self.attachment.reprocess! :medium, :thumb
      self.save(validate: false)
    end
  end

  def attachment_changed?
    self.attachment_file_name_changed? or
    self.attachment_content_type_changed? or
    self.attachment_file_size_changed? or
    self.attachment_updated_at_changed?
  end
end

1 个答案:

答案 0 :(得分:0)

这就是我用Sidekiq后台工作的方式:

# models/vignette.rb
class Profile < Document # I use polymorphism
  has_attached_file :attachment,
    styles: { square: "" },
    convert_options: { square: "-gravity north -thumbnail 300x300^ -extent 300x300+0+0 -quality 75" },
    default_url: ":parent_type/:class/:style/missing.png",
    path: "/documents/:parent_type/:id_partition/:class/:style/:basename.:extension"

  validates_attachment :attachment,
    content_type: { content_type: ["image/gif", "image/png", "image/jpg", "image/jpeg"] },
    size: { less_than: 1.megabyte }

  before_post_process :stop_process
  after_commit :process_styles

  def stop_process
    if !self.process and self.attachment_changed?
      self.process = true
      false
    end
  end

  def process_styles
    DocumentStyleProcess.perform_async(self.id) if self.process
  end

  def attachment_changed?
    self.attachment_file_size_changed? or
    self.attachment_file_name_changed? or
    self.attachment_content_type_changed? or
    self.attachment_updated_at_changed?
  end
end


# workers/document_style_process.rb
class DocumentStyleProcess
  include Sidekiq::Worker
  sidekiq_options queue: :first
  def perform document_id
    document = Document.find(document_id)
    document.attachment.assign(document.attachment)
    document.process = false
    document.save(validate: false)
  end
end

请注意,document.process是一个带有布尔类型的dedidacted列。 希望它有所帮助。