回形针处理器无法找到它的文件

时间:2011-01-25 00:51:45

标签: ruby-on-rails-3 file-upload callback paperclip rubyzip

以前:在创建或更新后在回形针附件上运行模型方法(回形针回调似乎不起作用)

编辑(当天晚些时候) 我想出了我的问题。处理器显然使用更新的文件,但在处理之前不保存任何文件。我将Zip :: ZipFile更改为打开'file'而不是'attachment.path',因为附件路径实际上还没有包含任何内容。这解决了第一个问题。现在我还有其他需要追查的问题。但下面的答案大多是正确的。

修改(1/31/2011):

所以我已经建议为我的附件创建一个处理器,它将执行所有必要的操作。到目前为止,它看起来应该有效;显然,处理器启动并执行所有初始化操作。但是,当我得到我想要访问上传的zip文件的点时,我收到一条错误消息,指出无法找到该文件。我的处理器的代码如下:

class Extractor < Processor
    attr_accessor :resolution, :whiny
    def initialize(file, options = {}, attachment = nil)
      super
      @file = file
      @whiny = options[:whiny].nil? ? true : options[:whiny]
      @basename = File.basename(@file.path, File.extname(@file.path))
      @attachment = attachment
      @instance = attachment.instance
    end
    def make
      # do your conversions here, you've got @file, @attachment and @basename to work with
      export_path = attachment.path.gsub('.zip', '_content')

      Zip::ZipFile.open(attachment.path) { |zip_file|
        zip_file.each { |image|
          image_path = File.join(export_path, image.name)
          FileUtils.mkdir_p(File.dirname(image_path))
          unless File.exist?(image_path)
            zip_file.extract(image, image_path)
            # ..stuff that it does..
          end
        }
      }
      # clean up source files, but leave the zip
      FileUtils.remove_dir(export_path)


      # you return a file handle which is the processed result
      dst = File.open result_file_path
    end
end

以下是我得到的错误内容:

Zip::ZipError in GalleriesController#create

File /home/joshua/railscamp/moments_on_three/public/assets/archives/delrosario.zip not found

Rails.root: /home/joshua/railscamp/moments_on_three
Application Trace | Framework Trace | Full Trace

config/initializers/extractor.rb:16:in `make'
app/controllers/galleries_controller.rb:32:in `new'
app/controllers/galleries_controller.rb:32:in `create'

Request

Parameters:

{"utf8"=>"✓",
 "authenticity_token"=>"0s4L4MrlqjDTMjzjgkUdvUxeHklZNOIShDhT6fgOICY=",
 "gallery"=>{"name"=>"DelRosario",
 "public"=>"0",
 "owner_id"=>"1",
 "shoot_date(1i)"=>"2011",
 "shoot_date(2i)"=>"1",
 "shoot_date(3i)"=>"31",
 "category_id"=>"1",
 "archive"=>#<ActionDispatch::Http::UploadedFile:0x00000004148d78 @original_filename="delrosario.zip",
 @content_type="application/zip",
 @headers="Content-Disposition: form-data; name=\"gallery[archive]\"; filename=\"delrosario.zip\"\r\nContent-Type: application/zip\r\n",
 @tempfile=#<File:/tmp/RackMultipart20110131-9745-14u347v>>},
 "commit"=>"Create Gallery"}

据我所知,它正在寻找正确位置的文件,但该文件似乎尚未上传,无法访问它。据我所知,Paperclip非常聪明,可以在尝试处理之前知道并等待附件上传。谁能发现我在这里做错了什么?

非常感谢。

旧东西:

我正在使用Rails 3和Paperclip开发一个照片库应用程序。管理员可以创建一个图库并上传包含一堆图像的zip文件。

我想要发生什么:

  
      
  1. 输入图库信息和zip文件以上传到表单。
  2.   
  3. 点击“创建图库”按钮。
  4.   
  5. 表单帖子,图库保存和zip文件上传。
  6.   
  7. 上传zip文件后,运行方法:extract_photos(顺便说一句,这段代码   作品)。   4.A.在此方法结束时,zip文件将被销毁。
  8.   
  9. 管理员被重定向到图库页面,其中包含所有照片(其中   画廊has_many照片)。
  10.   

我试图以不同的方式完成这项工作。

之前,我创建了一个控制器方法,允许管理员单击运行:extract_photos方法的链接。这在我的计算机上运行,​​但由于某种原因,服务器在客户端的计算机上路由这个问题。所以这是不行的。另外我认为这是一种丑陋的做法。

最近,我尝试使用回调方法。 after_save不起作用,因为它显然中断了表单POST并且文件没有上传,并且:extract_photos方法找不到该文件。

我在Paperclip github页面上检查了回调方法,并讨论了回调:

  

后处理之前和之后   一步,Paperclip回电话给   有一些回调的模型,允许   要更改或取消的模型   处理步骤。回调是   “before_post_process”和   “after_post_process”(被称为   处理前后   每个附件),和   附件特有的   “beforepost_process”和   “afterpost_process”。回调是   意图接近正常   ActiveRecord回调尽可能,所以   如果你返回false(具体 -   在a中返回nil是不一样的)   在过滤之前,后期处理   步骤将停止。在...中返回false   过滤后不会停止任何事情,   但你可以访问模型和   如有必要,附件。

我已经尝试过使用before_post_process和after_post_process,但它找不到运行该进程的文件,因此在调用这些方法时,该文件显然没有上传(我认为这很奇怪)。另外,当我尝试beforepost_process和afterpost_process时,我得到一个NoMethodError。

那么在创建或更新附件时,如何在附件上调用方法,但是在文件上传后并在正确的位置?

更新

我尝试了下面的代码,将我的提取方法代码移动到处理器的make方法中。我试图编写一个处理器比以前做得更远,但它仍然是一个禁忌。一旦我尝试打开上传的文件进行处理,该进程就会抛出异常,说该文件不存在。命名方案是正确的,但是仍然没有任何内容在进程被触发之前上传。有谁知道为什么会这样?

1 个答案:

答案 0 :(得分:2)

您可以编写自己的处理器来完成此任务。

在您的模型中声明回形针添加自定义处理器时

  has_attached_file :my_attachment, {
    :styles => {:original => {:processors => [:my_processor]}}
  }.merge(PAPERCLIP_SETTINGS)

然后编写自己的处理器并将其配置为config / initializers:

module Paperclip
  class MyProcessor < Processor
    attr_accessor :resolution, :whiny
    def initialize(file, options = {}, attachment = nil)
      super
      @file = file
      @whiny = options[:whiny].nil? ? true : options[:whiny]
      @basename = File.basename(@file.path, File.extname(@file.path))
      @attachment = attachment
    end
    def make
      # do your conversions here, you've got @file, @attachment and @basename to work with

      # you return a file handle which is the processed result
      dst = File.open result_file_path
    end
  end
end

我正在使用自定义处理器来处理类似于你正在做的事情,在中间进行大量处理和转换文件,它似乎运行良好。