Friday, December 02, 2011

Rails 3 Migration - Paperclip Processors

For those of you knee deep in a Rails 3 migration and have upgraded Paperclip, beware that the directory Paperclip loads custom processors from has changed. The problem with not knowing this before hand is you won't know things are busted until your app attempts to use the processor. In other words, this is a runtime exception. In our case this was a big deal, here's what was going on...

Children using our app have the ability to create drawings similar to MS Paint. When children save drawings they get uploaded to our servers, persisted locally, and subsequently uploaded to S3. After our Rails 3 upgrade, drawings were no longer getting persisted to our local storage nor S3. Root causing this was tricky because the persistence work is accomplished via DelayedJobs, so the exception wasn't in plain sight. After instrumenting our asynchronous task, we found out that Paperclip was failing to load our custom processor from the app/lib/paperclip_processors directory, which makes sense since our processor was located in the app/lib/paperclip directory. After checking the Paperclip release notes, sure enough they changed the processor directory.

Problem found, simple solution? You would think that the solution would be as simple as moving the process into a new directory, it wasn't. Our processor looked like this...

module Paperclip
  class Zeemark < Processor

    def initialize file, options = {}, attachment = nil
       // blah, blah...
    end

    def make
       // blah, blah...
    end
    
  end
end

The earlier version of Paperclip that we were using required custom processors to be part of the Paperclip module. This changed when we upgraded Paperclip, so simply copying our processor to app/lib/paperclip_processors introduced a different error. Specifically, Ruby complained that it cannot find the Zeemark class in file app/lib/paperlcip_processors/zeemark.rb, and rightly so. To fix this I stripped out the Paperclip module such that our processor looked like this...

class Zeemark < Paperclip::Processor

  def initialize file, options = {}, attachment = nil
     // blah, blah...
  end

  def make
     // blah, blah...
  end
    
end

Notice that I had to qualify parent Processor class with Paperclip::Processor. I hope someone out there finds this useful, deleting code is usually a good thing :-)

No comments: