sebastian.martinez

Making Paperclip work with Sinatra & Datamapper

Posted by sebastian.martinez
on February 10, 2010
I was working lately on a Sinatra project, and got fascinated on how fast you can get things up and running. Everything was beautiful, until I tried to upload a file using paperclip. Although Paperclip was originally built for rails [Ken Robertson](http://invalidlogic.com/dm-paperclip/) ported it to Datamapper. Let me explain in few steps how you can upload with Paperclip, using Datamapper. Start declaring your model like this:
class Resource
  include DataMapper::Resource
  include Paperclip::Resource

  property :id,     Serial

  has_attached_file :file,
                    :url => "/system/:attachment/:id/:style/:basename.:extension",
                    :path => "#{APP_ROOT}/public/system/:attachment/:id/:style/:basename.:extension"
end
You'll need to specify your :url and :path options as the ones built into dm-paperclip are merb centric which won't quite work. Also set APP_ROOT to where ever your application root directory with your static Sinatra folder is. Now your routes should look something like this:
post '/upload' do
  resource = Resource.new(:file => make_paperclip_mash(params[:file]))
  halt "There were some errors processing your request..." unless resource.save
end
And there's the tricky part, on the **make_paperclip_mash** method. Paperclip expects the file object loaded from the form to be in a different form than what is created by default. To fix this you should create a Mash (which is just a Hash, unless you're actually using merb):
def make_paperclip_mash(file_hash)
  mash = Mash.new
  mash['tempfile'] = file_hash[:tempfile]
  mash['filename'] = file_hash[:filename]
  mash['content_type'] = file_hash[:type]
  mash['size'] = file_hash[:tempfile].size
  mash
end
And that's it, now you can upload files using Paperclip right on your Sinatra app with Datamapper. You can check out the code of this example at: [sinatra_paperclip.rb](http://gist.github.com/291877)
| |