Intro to Acts As Attachment
Acts as Attachment is a Rails plugin that eases the process of handling uploaded files. It was originally written to store binary data in the database, but this only proved useful in limited use. It now handles attachments in the filesystem as well.
Features
- Choose either file system or active record storage
- Allow unlimited thumbnails with different sizes and filenames
- Uses RMagick for flexible image handling and resizing
- Extensively unit tested.
Installation
> script/plugin source http://svn.techno-weenie.net/projects/plugins
> script/plugin install acts_as_attachment
> rake test_plugins PLUGIN=acts_as_attachment
Simple Usage
Acts as Attachment is designed to be specified on multiple models in your application, rather than having a global Attachment model that other models depend on. For the purposes of this example, we’re going to allow DVD Collectors to upload covers of their collection.
Note: This is all using Rails v1.1.4. YMMV on older or newer versions.
> script/generate attachment_model dvd_cover
That command will generate the model stubs as well as an attachment migration to start. Here’s the database migration we’re going to use:
create_table :dvd_covers do |t|
t.column "dvd_id", :integer
t.column "content_type", :string
t.column "filename", :string
t.column "size", :integer
t.column "parent_id", :integer
t.column "thumbnail", :string
t.column "width", :integer
t.column "height", :integer
end
The columns content_type, filename, size, parent_id, and thumbnail are all vital for Acts as Attachment. Width and height are optional and used for images only. Here’s what the initial model will look like:
class DvdCover < ActiveRecord::Base
belongs_to :dvd
acts_as_attachment :storage => :file_system
validates_as_attachment
end
The validates method will set up the essential validations: the file size is within your limits, the content type matches what you want, and that the filename, size, and content_type fields are present. The default file size range goes from 1 byte to 1 megabyte. Since DVD Covers typically won’t be that large, let’s set some constraints. We’re going to use the :image shortcut to specify any common image type (gif, jpg, png).
class DvdCover < ActiveRecord::Base
belongs_to :dvd
acts_as_attachment :storage => :file_system, :max_size => 300.kilobytes, :content_type => :image
validates_as_attachment
end
Setting up a controller and some initial views does not require any special code. Acts as Attachment creates an uploaded_data= setter that does all the processing for you. Here’s everything you should need:
## app/controllers/dvd_covers_controller.rb
class DvdCoversController < ApplicationController
def index
@dvd_covers = DvdCover.find(:all)
end
def new
@dvd_cover = DvdCover.new
end
def show
@dvd_cover = DvdCover.find params[:id]
end
def create
@dvd_cover = DvdCover.create! params[:dvd_cover]
redirect_to :action => 'show', :id => @dvd_cover
rescue ActiveRecord::RecordInvalid
render :action => 'new'
end
end
## app/views/dvd_covers/index.rhtml
<h1>DVD Covers</h1>
<ul>
<% @dvd_covers.each do |dvd_cover| -%>
<li><%= link_to dvd_cover.filename, :action => 'show', :id => dvd_cover %></li>
<% end -%>
</ul>
<p><%= link_to 'New', :action => 'new' %></p>
## app/views/dvd_covers/new.rhtml
<h1>New DVD Cover</h1>
<% form_for :dvd_cover, :url => { :action => 'create' }, :html => { :multipart => true } do |f| -%>
<p><%= f.file_field :uploaded_data %></p>
<p><%= submit_tag :Create %></p>
<% end -%>
## app/views/dvd_covers/show.rhtml
<p><%= @dvd_cover.filename %></p>
<%= image_tag @dvd_cover.public_filename, :size => @dvd_cover.image_size %>
Comments
Comments are closed.
