Michael
Michael

Reputation: 683

Using Rails Paperclip gem to preprocess file before saving

I'm using the Paperclip gem on a Rails 3.2 app where users can upload a specialized file type that contains an image and other information (let's call it a ".elf" file).

I've written all the code needed to extract an image from an elf file via a class called ElfObject, and this works well when tested in the app's console. What I want to do is extract the image and other data from the .elf file before Paperclip saves it to AWS S3, store the other data in the model, and then save just the image object as the Paperclip attachment on S3. Here's the relevant code in the model:

class Photo < ActiveRecord::Base

  validates_attachment :attachment,
        :presence => true

  has_attached_file :attachment,
    :storage => :s3,
    [[S3 credentials removed]]

  before_attachment_post_process :import_photo

  attr_accessible :name, :attachment, :properties

  def import_photo
    if attachment_file_name =~ %r{^*\.elf$}
      origfile = attachment.queued_for_write
      elf = ElfObject.read(origfile)
      properties = elf.get_properties 
      attachment = elf.image.write "image_for_#{attachment_file_name}.png"
      save!      
    end
  end

When I try to upload this way on the app, it raises the error ArgumentError (Invalid argument 'file'. Expected String, got Hash.) from the line elf = ElfObject.read(origfile). If I try something like elf = ElfObject.read(origfile.path), I get NoMethodError (undefined method `path' for #).

Clearly, I'm not fully understanding how to access the file from Paperclip prior to it being posted--any ideas on where I'm going wrong and how to fix it?

Upvotes: 3

Views: 3922

Answers (1)

flynfish
flynfish

Reputation: 5867

It seems like the problem is exactly what the error is saying... that origfile is a Hash, rather than a String.

If that is the case then attachment.queued_for_write returns a Hash, which means you need to find the key that holds the file path string.

origfile = attachment.queued_for_write
p origfile.inspect #print it out so you can figure out what key holds the path

Edited answer try this:

def import_photo
  if attachment_file_name =~ %r{^*\.elf$}
    origfile = attachment.queued_for_write[:original]
    elf = ElfObject.read(origfile.path)
    properties = elf.get_properties 
    attachment = elf.image.write "image_for_#{attachment_file_name}.png"
    save!      
  end
end

Upvotes: 2

Related Questions