Attachments with CouchDB and Rails
In response to my recent CouchDB on Rails tutorial, somebody asked the following question:
Let's imagine, that you want to store a picture of grandma along with her contact-info – how exactly would I do that?
Well, Stf, here's the answer, with a picture of my actual grandma to illustrate!
The first thing you need to understand, CouchDB stores attachments in a special field, called _attachments. It can store multiple attachments inside that field, as an array. This means that you can upload a picture, and later come back and upload another picture, and they will be stored alongside each other.
I have implemented the attachments in such a way that it will display images inline, scaled down to 200px width. It's kind of a crude thumbnail. You can click on the picture to open it full size.
CouchRest and BasicModel make this pretty easy for us. We check whether the contact has any attachments, loop through the attachments, decide to display an image if it is png or jpg, otherwise link to the file name.
<% if @contact._attachments -%> <h2>Attachments</h2> <% @contact._attachments.each do |attachment_name, attachment_attributes| -%> <% if %w(image/jpeg image/png).include?(attachment_attributes['content_type']) -%> <% link_content = image_tag(attachment_contact_path(:id => @contact, :filename => attachment_name), :width => '200') -%> <% else -%> <% link_content = attachment_name -%> <% end -%> <%= link_to(link_content, attachment_contact_path(:id => @contact, :filename => attachment_name), :popup => true) %> <% end -%> <% end -%>
You may notice the attachment_contact_path – this is done with a little tweak in config/routes.rb:
map.resources :contacts, :member => {:attachment => :get}
Now we can add a controller action attachment which finds the attachment and renders it in full. This will involve displaying an image at full size, or launching a file in the appropriate application if it cannot be rendered inline.
def attachment @contact = Contact.find(database_name, params[:id]) metadata = @contact._attachments[params[:filename]] data = Contact.db(database_name).fetch_attachment(@contact.id, params[:filename]) send_data(data, { :filename => params[:filename], :type => metadata['content_type'], :disposition => "inline", }) end
Acknowledgements and thanks to topfunky for the peepcode-couchdb-code tutorial which gave me most of the information i needed to know in order to do this.
-
retail laptop batteries
-
lenovo Laptop Battery
-
leather corner suite
-
gisnap
-
gene123
-
payday loans
-
Going Green
-
Traveller
-
Leonardo
-
stf
-
aimee
-
Leonardo
