0

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

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

编辑(2011 年 1 月 31 日):

因此,我接受了建议,为我的附件创建一个处理器,它将执行所有必要的操作。到目前为止,它看起来应该可以工作;显然,处理器启动并执行所有初始化工作。但是,当我想访问上传的 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. 表单帖子、图库保存和 zip 文件被上传。
  4. 上传 zip 文件后,运行 :extract_photos 方法(顺便说一句,此代码有效)。4.a. 在此方法结束时,zip 文件被销毁。
  5. 管理员被重定向到包含所有照片的画廊页面(其中画廊 has_many 照片)。

我试图用几种不同的方式来完成这项工作。

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

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

我在 Paperclip github 页面上查看了回调方法,它谈到了回调:

在后处理步骤之前和之后,Paperclip 通过几个回调回调模型,允许模型更改或取消处理步骤。回调是“before_post_process”和“after_post_process”(在处理每个附件之前和之后调用),以及特定于附件的“beforepost_process”和“afterpost_process”。回调旨在尽可能接近正常的 ActiveRecord 回调,因此如果您在前过滤器中返回 false(特别是 - 返回 nil 不一样),后处理步骤将停止。在 after 过滤器中返回 false 不会停止任何操作,但您可以在必要时访问模型和附件。

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

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

更新

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

4

1 回答 1

2

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

在你的模型中声明回形针的东西时添加一个自定义处理器

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

然后编写您自己的处理器并将其放入配置/初始化程序:

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

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

于 2011-01-27T20:40:44.310 回答