Currently, the two most popular Image Upload extensions on rails are fleximage and paperclip. If you only process images in one breath, it is fleximage, of course, but if you still need other MP3, FLV, and other attachments for multi-State Association, then select paperclip. In general, paperclip is much better than the older upload plug-ins, such as acts_as_attachment, attachment_fu, and file_column.
Installation support
This plug-in requires external support for rmagick and ImageMagick. For installation instructions, refer to my other article.
Install paperclip
Ruby script/plugin install git: // github.com/thoughtbot/paperclip.git
Build the main framework
Two modules are involved: user and photo. We use user_id to differentiate albums.
Mysql> Create Database scripts; rails album-D mysqlcd album Ruby script/plugin install git: // your script/generate authenticated user sessions Ruby script/generate scaffold photo User: belongs_to is_avatar: Boolean
Configure the username and password of database. yml In the config directory.
The next step is very important. We need to add the attachment upload capability to photo.
Ruby script/generate paperclip photo imagerake DB: migrate
We name the attachment image, so that paperclip adds four prefixes to the photo model: <attachment> _ (the name of the attachment we just gave) <attachment> _ file_name, <attachment> _ file_size, <attachment> _ content_type, and <attachment> _ updated_at), that is, image_file_name, image_file_size, image_content_type, and metadata.
Delete index.html under the publicdirectory and add the routing rules:
Map. Root: Users
Modify users_controller and add index action
Def index; End
Add View
<% = Link_to "album", photos_path %>
Modify _user_bar.html. ERB
<Div id = "user_bar"> <% if logged_in? %> <% = Link_to "logout", logout_path,: Title => "logout" %> <% = link_to "Welcome, <strong >#{ current_user.login} </strong> ", CURRENT_USER %> <% else %> <% = link_to" login ", login_path ,: title => "login" %> <% = link_to "register", signup_path,: Title => "register" %> <% end %> </div>
Template application.html. ERB and global assistant layout_helper.rb
<% = javascript_include_tag: Defaults %> <% = H (yield (: Title) | controller. action_name) %> <% = stylesheet_link_tag 'blueprint', 'application' %> <% = yield (: Head) %>
<%-flash. each do | Name, MSG |-%> <% = content_tag: div, MSG ,: class => "# {name}" %> <%-end-%> <%-If show_title? -%>
<% = H yield (: Title) %>
<%-end-%> <% = render: partial => "users/user_bar" %> <% = yield %>
Module layouthelper def title (page_title, show_title = true) @ content_for_title = page_title.to_s @ show_title = show_title end def show_title? @ Show_title endend
Modify application_controller
Class applicationcontroller: record_not_found protected def record_not_found render: file => file. Join (rails_root, 'public', '404.html '),: Status => 404 endend
Start the server and create a user named situ zhengmei. We need to use its ID.
Modify the photo module to implement the upload capability.
New _form.html. ERB
<% Form_for @ photo,: HTML =>{: multipart => true} Do | f |%> <% = f. error_messages %> <% if logged_in? %> <% = F. hidden_field: user_id,: value => current_user.id %> <% end %> <p> <% = f. label: is_avatar %> <br/> <% = f. check_box: is_avatar %> </P> <p> <% = f. file_field: Image %> </P> <p> <button type = "Submit"> <% = button_name %> </button> </P> <% end %>
Modify new.html. ERB
<% Title "Upload image" %> <% = render: Partial => 'form',: locals => {: button_name => "Upload" }%> <% = link_to 'back', photos_path,: class => "button" %>
Modify show.html. ERB
<Div class = "figure"> <% = image_tag @ photo. image. url,: ALT => "it is in harmony with GFW! "%> <Div class =" legend "> All: <% = H @ photo. user. login %>; whether it is an Avatar: <% = @ photo. is_avatar %> </div> <% = link_to 'edit', [: Edit, @ photo],: class => "button" %> <% = link_to 'Return', photos_path,: class => "button" %>
Modify photo. Rb
Class photo
So that it can run, very simple!
Upload images through URLs Ruby script/generate migration addimageremoteurltophoto image_remote_url: stringrake DB: migrate
Modify the photo Model
Require 'open-Uri 'class photo: image_url_provided? Validates_presence_of: image_remote_url,: If =>: image_url_provided ?, : Message => 'invalid address 'private def image_url_provided? ! Self. image_url.blank? End def download_remote_image self. image = do_download_remote_image self. image_remote_url = image_url end def do_download_remote_image IO = open (URI. parse (image_url) def Io. original_filename; base_uri.path.split ('/'). last; end Io. original_filename.blank? ? Nil: Io rescue # Catch URL errors with validations instead of exceptions (errno: enoent, openuri: httperror, Etc...) endend
Modify _form.html. ERB
<% Form_for @ photo,: HTML =>{: multipart => true} Do | f |%> <% = f. error_messages %> <% if logged_in? %> <% = F. hidden_field: user_id,: value => current_user.id %> <% end %> <% if action_name = "new" %> <p> <% = f. label: is_avatar, "whether to be an avatar" %> <% = f. check_box: is_avatar %> </P> <% end %> <p> <% = f. file_field: Image %> <br/> or URL <% = f. text_field: image_url %> </P> <p> <button type = "Submit"> <% = button_name %> </button> </P> <% end %>
The upload is successful!
Add multiple styles and Verification
#........................ Has_attached_file: image,: default_url => "/images/rails.png",: styles =>{: thumb => "100x100 #",: gallery => "150x150>",: Avatar => "200x200>"} # The image cannot be deleted with this option # validates_attachment_presence: Image validates_attachment_size: image ,: less_than => 5. megabytes validates_attachment_content_type: image,: content_type => ['image/gif', 'image/PNG ', 'image/X-PNG', 'image/JPEG ', 'image/pjpeg ', 'image/jpg'] #........................
Delete Image
Because paperclip stores uploaded items on the hard disk by default, calling destroy action can only delete the data in the database, but cannot delete the related images. Therefore, we need to add the image deletion logic to the model.
#================================== OthersCode========================================================== ============== Delete an image ====================================== def delete_image = (value) @ delete_image =! Value. to_ I .zero? End def delete_image !! @ Delete_image end alias_method: delete_image ?, : Delete_image before_validation: clear_image def clear_image self. Image = nil if delete_image? &&! Image. Dirty? End #================================== other code ====== ====================
Modify _form.html. ERB
<% Form_for @ photo,: HTML =>{: multipart => true} Do | f |%> <% = f. error_messages %> <% if logged_in? %> <% = F. hidden_field: user_id,: value => current_user.id %> <% end %> <% if action_name = "new" %> <p> <% = f. label: is_avatar, "whether to be an avatar" %> <% = f. check_box: is_avatar %> </P> <% end %> <p> <% = f. file_field: Image %> <br/> or URL <% = f. text_field: image_url %> </P> <%-unless @ photo. new_record? |! @ Photo. image? -%> <Div> <% = image_tag (@ photo. image. URL (: Gallery),: ALT => 'photo',: Title => 'current image') %> <p> <% = f. label (: delete_image, 'delete image') %> <% = f. check_box (: delete_image) %> </P> </div> <%-end-%> <p> <button type = "Submit"> <% = button_name %> </button> </ p> <% end %>
Modify edit.html. ERB
<% Title "Edit image" %> <% = render: Partial => 'form',: locals => {: button_name => "Update" }%> <% = link_to 'enlarge ', @ photo,: class => "button" %> <% = link_to' Return ', photos_path ,: class => "button" %>
Modify update action
Def update @ photo = photo. Find (Params [: Id]) If @ photo. update_attributes (Params [: Photo]) Message = @ photo. delete_image ?? "Image deleted! ":" Image updated! "Flash [: Notice] = message redirect_to (@ photo) else render: Action =>" edit "end
<H1> listing photos
Finally, paperclip is unfriendly to Windows. The most common problem in the Google discussion group is the "is not recognized by the 'identify' command" error, however, I have never met this blog post. It is absolutely no problem in the Linux environment.