Wednesday, February 11, 2009

IMAGE UPLOADING

Image uploading is easy in ruby on rails by using attachment_fu plugin

To install attachment_fu
ruby script/plugin install http://svn.techno-weenie.net/projects/plugins/attachment_fu/


Then u need to design table in migration like

here we will take user images
class CreateUserImages < ActiveRecord::Migration
def self.up
create_table "user_images",:force => true do |t|
t.column "user_id", :integer
t.column "primary", :boolean
t.column "created_at", :datetime

# Required attributes for attachment_fu plugin
t.column "filename", :string, :limit => 255
t.column "path", :string, :limit => 255
t.column "content_type", :string
t.column "size", :integer
t.column "width", :integer
t.column "height", :integer
t.column "parent_id", :integer
t.column "thumbnail", :string
end

def self.down
drop_table :user_images
end
end


In model we need to customize validations

class UserImage < ActiveRecord::Base
belongs_to :user

has_attachment :content_type => :image,
:storage => :file_system,
:path_prefix => 'public/website',
:size => 1.kilobyte..5.megabytes,
:resize_to => '279x116',
:thumbnails => {:thumb => '100x100>' }
validates_as_attachment
validates_uniqueness_of :filename

def full_filename(thumbnail = nil)
file_system_path = (thumbnail ? thumbnail_class : self).attachment_options[:path_prefix].to_s
File.join(RAILS_ROOT, file_system_path, thumbnail_name_for(thumbnail))
end
end


And in User model

class User < ActiveRecord::Base
has_many :user_images


def primary_image
user_images.find_by_primary(true)
end
end


Here in controller only to display and create

class UserImagesController < ApplicationController
def new
@image = UserImage.new
respond_to do |format|
format.html
end
end

def create
# Required for Windows machines. Uncomment if you using Windows
# sleep(1)
user_data = {:user => current_user, :primary => current_user.images.empty? }

@image = UserImage.new(params[:image].merge(user_data))

respond_to do |format|
if @image.save
flash[:success] = "image successfully uploaded"
format.html { redirect_to(edit_user_path(current_user)) }
else
format.html { render :action => "new" }
end
end
end
end


And in new.rhtml

Current Primary Photo


<% if(@current_user.image.nil?) %>
<%= image_tag("default.png") %>
<% else %>
<%= image_tag(@current_user.primary_image.public_filename(:medium)) %>
<% end %>

Upload a new photo


<%= error_messages_for :image %>

<% form_for(:image, :url => user_images_path,
:html => { :multipart => true }) do |f| %>

Select a photo to upload

Photo: <%= f.file_field 'uploaded_data' %>
<%= submit_tag 'Upload Photo' %>
<% end %>


Follow the steps
Rake db:migrate
Then Script/server


If u want ur own validation to image then here are some key points
has_attachment(options = {})

* :size
o Range of sizes allowed.
o (1..1.megabyte) is the default. This overrides the :min_size and :max_size

* :resize_to
o Used by RMagick to resize images.
o Pass either an array of width/height, or a geometry string.

* :thumbnails
o Specifies a set of thumbnails to generate.
o This accepts a hash of filename suffixes and RMagick resizing options.
o This option need only be included if you want thumbnailing.
o :thumbnail_class
o Set which model class to use for thumbnails.o This current attachment class is used by default.

* :path_prefix
o path to store the uploaded files.
o path to store the uploaded files.
o Uses public/#{table_name} by default for the filesystem, and just #{table_name} for the S3 backend.
o Setting this sets the :storage to :file_system.

* :storage
o Specifies the storage system to use.
o Defaults to :db_file. Options are :file_system, :db_file, and :s3.

* :processor
o Sets the image processor to use for resizing of the attached image.
o Options include ImageScience, Rmagick, and MiniMagick. Default is whatever is installed.

* :content_type
o Allowed content types.
o Allows all by default. Use :image to allow all standard image types.

* :min_size
o Minimum size allowed.
o 1 byte is the default.

* :max_size
o Maximum size allowed.
o 1.megabyte is the default.



Reference link is: http://www.jumbabox.com/2008/06/attachment_fu-tutorial/

3 comments:

le gordo said...

hi there
this post has been great BUT i am getting problems in the primary_image method defined in the model.

When I load the webpage (view), I seem to get this error, "undefined method `find_by_primary' for #".

I tried a few things but can't figure it out! help :)

le gordo said...

sorry, it works now cause i renamed the attribute, "primary" to "is_primary".
cheers!

le gordo said...

hi there

when you customise your validation for the User class for the image (ie has_attachments), are you therefore not using the "styles" that paperclip has to offer?
Is there any way for us to still use "styles"?
Without the custom validation and using the default paperclip validation methods such as validate_content_type, my application is currently dying badly when i upload a non image file. Problem is, the paperclip related errors are not showing.

help! :D