This is probably one of the most important plugin in Rails. Eve you ever thought about add some attachments to some model? Add photos, videos, mp3, pdf etc. Of course yes!
Paperclip makes your life much simpler, and adds to the ActiveRecord support to upload files.
There is also a well know plugin called Attachement_fu that does the exact same thing, but I sincerely prefer paperclip because it allows me to upload files directly to the file system and not to a database (I try Attachement_fu first but I couldn´t get it work on my application).
Like you maybe have heard yet, a file system it’s faster than a database, regarding file upload and download. Although using a file system raises the common security problem. And no, I not thinking about keep my files on the public folder. I use one protocol called sendfile that allow my apache server to send files that are in private folders (Try XSendFile plugin).
You can found much more information about this plugin here:
http://www.thoughtbot.com/projects/paperclip
This is a piece of my photo model:
has_attached_file :source,
:styles => { :medium => "560x480>",
:thumb => "60x60>" ,
:tiny => "30x30>" ,
},:url => "/photos/:id/", :path => ":rails_root/assets/photos/:id/:style/:basename.:extension"
validates_attachment_presence :source
validates_attachment_content_type :source,
:content_type => ["image/jpeg", "image/png", "image/gif" ,"image/pjpeg","image/x-png"],
:message => "Oops! Make sure you are uploading an image file."
validates_attachment_size :source,
:less_than => 10.megabyte,
:message => "max size is 10M"
As you can see with Paperclip I can verify the size and type of my uploaded file. Also with Paperclip I can create photos with different sizes.
Note: Do not forget to install ImageMagick in your server machine. Also, if you are using video upload, do not forget about ffmpeg to convert the file and maybe get some nice video picture preview to use in your application.
Continuing with the examples, this is a piece of my video.rb model.
def convert_command
flv = File.join(File.dirname(source.path), "#{id}.flv")
File.open(flv, 'w')
command = <<-end_command
ffmpeg -y -i #{ source.path } -f flv #{ flv }
end_command
command.gsub!(/\s+/, " ")
end
This is a convert method. It creates a new flv file.
def thumb_command
command2 = <<-end_command
ffmpeg -itsoffset -5 -i #{ self.source.path } -y -vcodec mjpeg -vframes 1 -an -f rawvideo -s 60x60 assets/videos/#{ self.id }/original/thumb.jpg
end_command
command2.gsub!(/\s+/, " ")
end
This is a thumb creator. It creates a picture of the movie in second five with 60x60 pixels (5 seconds it’s nice, but remembers, some videos may appear black in second 5, I still not have the solution for that).
In order to upload videos and music the model that represent’s the content must act as a state machine. That means the file will pass for different stats until gets converted (See Act as State Machine on http://agilewebdevelopment.com/plugins/acts_as_state_machine)
So in my video model for instance I can do:
acts_as_state_machine :initial => :pending
state :pending
state :converting
state :converted, :enter => :set_new_filename
state :error
event :convert do
transitions :from => :pending, :to => :converting
end
event :converted do
transitions :from => :converting, :to => :converted
end
event :failed do
transitions :from => :converting, :to => :error
end
This code says pretty much everything. The video file passes throw different stages (pending, converting, converted or error).
Cheers,
Hélder Loureiro
Wednesday, October 28, 2009
Subscribe to:
Post Comments (Atom)

No comments:
Post a Comment