sebastian.martinez

Making Paperclip work with Sinatra & Datamapper 4

Posted by sebastian.martinez
on Wednesday, February 10

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 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

|

If you have found this material to be useful, you might
consider recommending me on Working With Rails.

Comments

Leave a response

  1. Jonas Nicklas Jonas NicklasFebruary 11, 2010 @ 02:51 AM

    Just a heads up that CarrierWave (http://github.com/jnicklas/carrierwave) works out of the box with DataMapper and Sinatra.

  2. Sebastian Martinez Sebastian MartinezFebruary 11, 2010 @ 03:22 PM

    Hi Jonas, didn’t know about that, sounds great! Thanks for the heads up. This post was not intended to point out the best upload solution for Sinatra though, but to show how to make Paperclip work with it.

    Cheers!

  3. Ken Robertson Ken RobertsonFebruary 17, 2010 @ 11:30 AM

    I’ll admit that dm-paperclip has fallen behind, though hoping to start fresh with it once I start working more with Rails3. If you have any changes to commit back though, let me know.

  4. Tobias Steele Tobias SteeleJune 13, 2010 @ 09:56 PM

    Thanks for this tutorial! I’m just starting with Sinatra/paperclip. I was wondering if you could please suggest how to do simple post file uploads to a directory on the server? My app doesn’t need a database – I’ll just need to be able to reference the uploaded file later.

    Should I use paperclip, or is there a better/easier way?

    Thanks again!

Comment