
POST message有一种特殊的类型叫做:multipart/form-data,这是一种又一种特定的form产生的message,这种form是包含<input type="file"...>的form。在客户端<input type="file"...>标签显示成这样的形式:
为了说明问题,我们举例来看看,先建立数据库:
create table pictures (
id int not null auto_increment,
comment varchar(100),
name varchar(200),
content_type varchar(100),
data blob,
primary key (id)
);
建立controller:
class UploadController < ApplicationController
def get
@picture = Picture.new
end
end
建立get template:
<%= error_messages_for("picture") %>
<%= form_tag({:action => 'save'}, :multipart => true) %>
Comment: <%= text_field("picture", "comment") %>
<br/>
Upload your picture: <%= file_field("picture", "picture") %>
<br/>
<%= submit_tag("Upload file") %>
<%= end_form_tag %>
建立model:
class Picture < ActiveRecord::Base
validates_format_of :content_type, :with => /^image/,
:message => "--- you can only upload pictures"
def picture=(picture_field)
self.name = base_part_of(picture_field.original_filename)
self.content_type = picture_field.content_type.chomp
self.data = picture_field.read
end
def base_part_of(file_name)
name = File.basename(file_name)
name.gsub(/[^\w._-]/, '')
end
end
这里定义的 picture= method,会读取表单中 name=picture[picture] 的标签的数据,因为文件对象比较复杂,不能直接存到数据库中的某个列中,所以需要进行复杂的处理,html中文件对象的可以分为3个部分:
| 文件的名称 | 上传时候的文件名字 | 比如:1.gif |
| 文件的类型 | 上传的文件的类型 | 比如:image/gif |
| 文件的数据部分 | 文件的数据部分 |
上面的红色字体对应了处理文件对象的部分
扩充controller,添加save action:
def save
@picture = Picture.new(params[:picture])
if @picture.save
redirect_to(:action => 'show', :id => @picture.id)
else
render(:action => :get)
end
end
扩充controller,添加picture action:
def picture
@picture = Picture.find(params[:id])
send_data(@picture.data,
:filename => @picture.name,
:type => @picture.content_type,
:disposition => "inline")
end
注意send_data method 返回值被 url_for method接受,用于显示图片,我们这里要注意一下 :filename和:type这2个key,在用户使用右键---另存为 的时候,文件名和类型将被显示出来
定义show action:
def show
@picture = Picture.find(params[:id])
end
show template:
<h3><%= @picture.comment %></h3>
<img src="<%= url_for(:action => "picture", :id => @picture.id) %>"/>
这里使用url_for方法来显示图片
Powered by Haiwit