File Upload
Using acts_as_attachment; see also attachment_fu, file_column
- Install acts_as_attachment
script/plugin source http://svn.techno-weenie.net/projects/plugins script/plugin install acts_as_attachment
- Create a model for storing photos
script/generate attachment_model photo
edit the generated migration
class CreatePhotos < ActiveRecord::Migration def self.up create_table :photos do |t| t.column "coffee_house_id", :integer, :null => false t.column "content_type", :string t.column "filename", :string t.column "size", :integer # used with thumbnails, always required t.column "parent_id", :integer t.column "thumbnail", :string # required for images only t.column "width", :integer t.column "height", :integer # required for db-based files only #t.column "db_file_id", :integer end # only for db-based files # create_table :db_files, :force => true do |t| # t.column :data, :binary # end end def self.down drop_table :photos # only for db-based files # drop_table :db_files end endrun migration
rake db:migrate
edit the generated model
class Photo < ActiveRecord::Base belongs_to :coffee_house acts_as_attachment :storage => :file_system, :content_type => :image, :thumbnails => {:normal => '300', 'thumb' => '75'} validates_as_attachment end - Create controller actions and views
add actions to coffee_house_controller
def new_photo @photo = Photo.new(:coffee_house_id=>params[:id]) end def create_photo @photo = Photo.new(params[:photo]) if @photo.save redirect_to :action => 'show', :id => @photo.coffee_house_id else render :action => 'new_photo' end end def destroy_photo @photo = Photo.find_by_id(params[:id]) redirect_to :action => 'index' and return unless @photo @coffee_house = @photo.coffee_house @photo.destroy render :action => 'show' endGETs should be safe - update for new actions (find this snippet in coffee_house_controller.rb and add the bolded action names)
# GETs should be safe (see http://www.w3.org/2001/tag/doc/whenToUseGet.html) verify :method => :post, :only => [ :destroy, :create, :update, :create_photo, :destroy_photo ], :redirect_to => { :action => :list }create view in app/views/coffee_house/new_photo.rhtml
<h1>New photo</h1> <%= error_messages_for :photo %> <% form_for :photo, :url => { :action => 'create_photo' }, :html => { :multipart => true } do |f| -%> <p><%= f.hidden_field :coffee_house_id %></p> <p><%= f.file_field :uploaded_data %></p> <p><%= submit_tag :Create %></p> <% end -%> - Integrate with the CoffeeHouse application
Add relation to app/models/coffee_house.rb
has_many :photos, :dependent => :destroy
Add a gallery and new photo link to app/views/coffee_house/show.rhtml
<% for column in CoffeeHouse.content_columns %> <p> <%= column.human_name %>: <%=h @coffee_house.send(column.name) %> </p> <% end %> <% for photo in @coffee_house.photos -%> <p><%= photo.filename %></p> <%= image_tag photo.public_filename('thumb') %> <%= image_tag photo.public_filename, :size => photo.image_size %> <% end -%> <p><%= link_to 'Add photo', :action => 'new_photo', :id => @coffee_house %></p> <%= link_to 'Edit', :action => 'edit', :id => @coffee_house %> | <%= link_to 'Back', :action => 'list' %> - File storage
- create directory public/photos
- make it recursively writeable for the web server
- RMagick integration
add at the end of config/environment.rb:
require 'RMagick'