sebastian.martinez

Making Paperclip work with Sinatra & Datamapper 3

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.

santiago.pastorino

Paperclip file rename 0

Posted by santiago.pastorino
on Tuesday, July 14

While developing an application with Sebastián that allow users to upload videos with some file name restrictions, meaning that it must contain only A-Z and 0-9 digits, underscores (_) as a valid component as well, and also the name must be preceded by it’s own #id, we came up with the need of applying this custom filter to each uploaded video. After doing some research on paperclip source code and internet tutorials, we suggest the following solution:

class Video < ActiveRecord::Base
  has_attached_file :video,
    :path => ":rails_root/public/system/:attachment/:id/:style/:normalized_video_file_name",
    :url => "/system/:attachment/:id/:style/:normalized_video_file_name" 

  Paperclip.interpolates :normalized_video_file_name do |attachment, style|
    attachment.instance.normalized_video_file_name
  end

  def normalized_video_file_name
    "#{self.id}-#{self.video_file_name.gsub( /[^a-zA-Z0-9_\.]/, '_')}" 
  end
end
What are we doing here? Easy, in has_attached_file we edit the way paperclip returns the path and url by default, the most relevant components when saving and loading the file in order to display it. Paperclip default values are:
path default => ":rails_root/public/system/:attachment/:id/:style/:filename" 
url default => "/system/:attachment/:id/:style/:filename"

Values preceded by ’:’ are the standard interpolations paperclip has. For further information on this visit http://wiki.github.com/thoughtbot/paperclip/interpolations.

What we did was change * with *:normalized_video_file_name in both path and url, being the second a custom interpolation and then added the ‘normalized_video_file_name’ method to video.rb.

By doing this we not only achieve a way for paperclip to handle the file by this normalized way, but also have a method to access the normalized file name, plus being able to access the original file name through paperclip video_file_name method.

So remember on video_file_name you have the uploaded filename and on normalized_video_file_name you have the server filename.

|

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