Rails 2.3下可以用的上传文件

One of my project Lucas needs to enable users to upload pictures as their logos. How to get things done? In the book Agile Web Development with Rails, I’ve found a way.

All together, the code counts less than 50 lines.

Firstly we have to create a table to record the data. The columns should at least contain id, content-type and data, and the SQL maybe like follows:

    CREATE TABLE IF NOT EXISTS `logos` (
`id` int(10) unsigned NOT NULL auto_increment,
`data` blob NOT NULL,
`content_type` varchar(30) collate utf8_bin NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT;


OK. It’s time to start coding, and we have to create the model Logo and controller Logo.

    ruby script/generate model Logo
ruby script/generate controller Logo get got show


In app/controllers/logo_controller.rb, there’re 3 actions. “get” will display a upload form, and “got” is the final page if upload succeeded, which show the picture by a tag. Of course, we use the “show” action to get data from the database and send to user.

Let’s start coding here:

app/models/logo.rb

class Logo < ActiveRecord::Base
validates_format_of :content_type , :with => /^image/, :message => "你只能上传图片"

def uploaded_logo=(logo_field)
self.content_type = logo_field.content_type.chomp
self.data = logo_field.read
end
end


The function “uploaded_logo” contains a little bit magic. Continue to see the upload form you’ll see why use this.

app/views/logo/get.rhtml

<%= error_messages_for("logo") -%>
<% form_for (:logo, :url=>{:action => 'save'} , :html => {:multipart => true} ) do |form|%>
<%= form.file_field("uploaded_logo") %> 
<%= submit_tag("Upload")%>
<%end%>


In the above template file, we created a upload field named “uploaded_logo”, so when the form is submitted, the function “uploaded_logo=” will be called . Of course, we need to edit the controller.

app/controllers/logo_controller.rb

    class LogoController < ApplicationController
def get
@logo = Logo.new
end

def save
@logo = Logo.new(params[:logo])
if @logo.save
redirect_to(:action => "got" , :id => @logo.id)
else
render :action=>"get"
end
end

def view
@logo = Logo.find(params[:id])
send_data(@logo.data, :type=>@logo.content_type,:disposition=>"inline")
end

def got
@logo = Logo.find(params[:id])
end
end


Take a look at the “view” action, it makes good use of function “send_data”. Now we’re able to get the picture via /view/id , which contains extra content-type message in the header. Now it’s the last part of this demo, the template of action “got”.

app/views/logo/got.rhtml

<img src="<%= url_for :action=>"view", :id=>@logo.id %>" />


Of course, to make the pages better, you have to create a layout for logo. Besides, you may need to do some verification before enabling the upload.

If you want to store the pictures in files, just read the data out and write to a new file, which is in a visitable folder.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值