`

使用attachment_fu上传图像

阅读更多
按照说明一步一步来,首先声明了一个model,用来保存图片信息,顺便在controller中实现图片上传,显示等功能,定义的model如下:
ruby 代码
 
  1. class Upfile < ActiveRecord::Base  
  2.   has_attachment :content_type=>:image,:max_size=>2.megabyte,:thumbnails=>{:small=>'200x200>', :middle=>'400x400>'},:storage=>:db_file  
  3.   validates_as_attachment  
  4. end  

这里我没有如例子给出的一般采用文件系统,而是使用了数据库来保存图像(如果需要保存在数据库中,需要另外定义一个model和一个数据表,Mode名字叫做DbFile)。各个参数的意义如下:

  This method accepts the options in a hash:
    :content_type     # Allowed content types.
                      # Allows all by default.  Use :image to allow all standard image types.
    :min_size         # Minimum size allowed.
                      # 1 byte is the default.
    :max_size         # Maximum size allowed.
                      # 1.megabyte is the default.
    :size             # Range of sizes allowed.
                      # (1..1.megabyte) is the default.  This overrides the :min_size and :max_size options.
    :resize_to        # Used by RMagick to resize images.
                      # Pass either an array of width/height, or a geometry string.
    :thumbnails       # Specifies a set of thumbnails to generate.
                      # This accepts a hash of filename suffixes and RMagick resizing options.
                      # This option need only be included if you want thumbnailing.
    :thumbnail_class  # Set which model class to use for thumbnails.
                      # This current attachment class is used by default.
    :path_prefix      # path to store the uploaded files.
                      # Uses public/#{table_name} by default for the filesystem, and just #{table_name} for the S3 backend. 
                      # Setting this sets the :storage to :file_system.
    :storage          # Specifies the storage system to use..
                      # Defaults to :db_file.  Options are :file_system, :db_file, and :s3.
    :processor        # Sets the image processor to use for resizing of the attached image.
                      # Options include ImageScience, Rmagick, and MiniMagick.  Default is whatever is installed.
   

  Examples:
    has_attachment :max_size => 1.kilobyte
    has_attachment :size => 1.megabyte..2.megabytes
    has_attachment :content_type => 'application/pdf'
    has_attachment :content_type => ['application/pdf', 'application/msword', 'text/plain']
    has_attachment :content_type => :image, :resize_to => [50,50]
    has_attachment :content_type => ['application/pdf', :image], :resize_to => 'x50'
    has_attachment :thumbnails => { :thumb => [50, 50], :geometry => 'x50' }
    has_attachment :storage => :file_system, :path_prefix => 'public/files'
    has_attachment :storage => :file_system, :path_prefix => 'public/files',
                   :content_type => :image, :resize_to => [50,50]
    has_attachment :storage => :file_system, :path_prefix => 'public/files',
                   :thumbnails => { :thumb => [50, 50], :geometry => 'x50' }
    has_attachment :storage => :s3


接下来定义Model对应的Migration
Upfile:
ruby 代码
 
  1. class CreateUpfiles < ActiveRecord::Migration  
  2.   def self.up  
  3.     create_table :upfiles do |t|  
  4.       t.column :size,:integer,:null=>false  
  5.       t.column :content_type,:string,:null=>false  
  6.       t.column :filename,:string,:null=>false  
  7.       t.column :height,:integer  
  8.       t.column :width,:integer  
  9.       t.column :parent_id,:integer  
  10.       t.column :thumbnail,:string  
  11.       t.column :db_file_id,:integer  
  12.     end  
  13.   end  
  14.   
  15.   def self.down  
  16.     drop_table :upfiles  
  17.   end  
  18. end  

DbFile:
ruby 代码
 
  1. class CreateDbFiles < ActiveRecord::Migration  
  2.   def self.up  
  3.     create_table :db_files do |t|  
  4.       t.column :data:binary  
  5.     end  
  6.   end  
  7.   
  8.   def self.down  
  9.     drop_table :db_files  
  10.   end  
  11. end  

各个字段对应的解释如下:
Fields for attachment_fu metadata tables...
  in general:
    size,         :integer  # file size in bytes
    content_type, :string   # mime type, ex: application/mp3
    filename,     :string   # sanitized filename
  that reference images:
    height,       :integer  # in pixels
    width,        :integer  # in pixels
  that reference images that will be thumbnailed:
    parent_id,    :integer  # id of parent image (on the same table, a self-referencing foreign-key).
                            # Only populated if the current object is a thumbnail.
    thumbnail,    :string   # the 'type' of thumbnail this attachment record describes. 
                            # Only populated if the current object is a thumbnail.
                            # Usage:
                            # [ In Model 'Avatar' ]
                            #   has_attachment :content_type => :image,
                            #                  :storage => :file_system,
                            #                  :max_size => 500.kilobytes,
                            #                  :resize_to => '320x200>',
                            #                  :thumbnails => { :small => '10x10>',
                            #                                   :thumb => '100x100>' }
                            # [ Elsewhere ]
                            # @user.avatar.thumbnails.first.thumbnail #=> 'small'
  that reference files stored in the database (:db_file):
    db_file_id,   :integer  # id of the file in the database (foreign key)
   
Field for attachment_fu db_files table:
  data, :binary # binary file data, for use in database file storage

搞定了数据库,接下来让我们回到controller,在UpfileController中定义几个方法:upload,showimage,image,upload用来控制上传文件,showimage用来显示一幅图片,image用来得到某幅图片数据。一下是三个action的代码:

ruby 代码
 
  1. class UpfileController < ApplicationController  
  2.   def upload  
  3.     if request.post?  
  4.       @attachable_file = Upfile.new(params[:attachment_metadata])  
  5.       if @attachable_file.save  
  6.         flash[:notice] = 'Attachment was successfully created.'  
  7.         redirect_to :action=>:showimage,:id=>@attachable_file.attributes["id"]  
  8.       end  
  9.     end  
  10.   end  
  11.   
  12.   def showimage   
  13.     @image = Upfile.find(:first,:conditions=>{:id=>params[:id],:parent_id=>nil})  
  14.   end 
  15.   
  16.   def image  
  17.     @image = Upfile.find(:first,:conditions=>{:id => params[:id]})  
  18.     send_data(@image.db_file.data,:filename=>@image.attributes["filename"],:type=>@image.attributes["content_type"],:disposition=>"inline")  
  19.   end  
  20. end  

upload.rhtml:
ruby 代码
 
  1. <h1>Upfile#upload</h1>  
  2. <% form_for(:attachment_metadata:url => {:action=>"upload"}, :html => {:multipart=>true}) do |form| -%>  
  3. select image to upload: <%= form.file_field :uploaded_data %><p>  
  4. <%= submit_tag "upload now" %>  
  5. <% end -%>  

showimage.rhtml
ruby 代码
 
  1. <% if @image -%>  
  2.   <% if @image.image? -%>  
  3.     <img src="<%= url_for(:action=>:image,:id=>@image.attributes["id"]) %>" /> 
  4.   <% end -%>  
  5. <% end -%>  

经过这样设置,在upload一个图像后,会自动转到刚上传图像显示的页面。

不过经过我现在实践,这个方法还有一些问题,主要就是读取数据库中图像时,若图像比较大,则只能读取前65535个字节的数据,另外,@image.db_file.data.class是string
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics