论坛首页 入门技术论坛

上传文件

浏览 1350 次
锁定老帖子 主题:上传文件
该帖已经被评为新手帖
作者 正文
   发表时间:2009-03-17   最后修改:2009-03-17
这两天做文件上传,碰到不少问题。把过程记录下来吧。

我没有用插件,自己照着《Ruby on Rails敏捷开发最佳实践》这本书上的例子写的。
数据库迁移文件:
class CreatePeople < ActiveRecord::Migration
  def self.up
    create_table :people do |t|
       t.column :name, :string
       t.column :picture, :string     
    end
  end

  def self.down
    drop_table :people
  end
end

控制器:
class UploadController < ApplicationController  
#  before_filter:set_charset  
#  def set_charset
#    response.headers["Content-Type"] = "text/html; charset=utf-8"
#  end  
  
  def get
    @person=Person.new    
  end
  
  def create
    @person=Person.new(params[:person])    
    if @person.save
      if params[:person][:photo].size>0
        @person.add_picture
      end
      flash[:notice]='成功'
      redirect_to :action=>"show",:id=>@person
    else
      render :action=>'get'
    end
  end
  
  def show
    @person = Person.find(params[:id])
    require 'iconv'
    conv = Iconv.new("utf-8", "ISO-8859-1")
    result = conv.iconv("/images/pictures/"+@person.picture)
    result << conv.iconv(nil)
    conv.close	
    @picture_path=result
  end  
end

model类:
class Person < ActiveRecord::Base
require 'iconv'
  def make_file_name(name)
   file_ex_name = name
            return file_ex_name
 end
  def photo=(photo)
    if photo.size>0 then
      t=Time.now
      #@name=params[:person][:name]
      @content_size=photo.size
      @file_data=photo.read
      @filetype=photo.content_type
      filename=photo.original_filename
      #@filename_old=File.basename(filename).split(".")[0]
      @filetype_suffix=File.basename(filename).split(".")[1]
      #@new_filename=t.year.to_s+"-"+t.month.to_s+"-"+t.day.to_s+"."+@filetype_suffix
      @new_filename=make_file_name(name.to_s)+"."+@filetype_suffix
    end
  end

  def add_picture
    if @file_data then
      File.open(self.path_to_file(@new_filename),"wb") do |f|
        f.write(@file_data)
        self.update_attributes(:picture=>@new_filename)
      end
    end
  end
  def path_to_file(param_filename)   
    conv = Iconv.new("GBK","utf-8")
    result = conv.iconv(RAILS_ROOT+"/public/images/pictures/"+param_filename)
    result << conv.iconv(nil)
    conv.close
    return result
  end
#   def validate
#    if @filetype!=nil
#      errors.add("","只能上传图片")unless @filetype=~/^image/
#    end
#    if @content_size!=nil
#      errors.add("","上传的图片大学不能炒股2MB") if @content_size>2*1024*1024
#    end
#  end
end

视图:
get.rhtml
<%=form_tag({:action=>'create',:id=>@person},:multipart=>true) %>
 
 <%=error_messages_for'person'%>
 <p><label for="person_name">用户名:</label>
 <%=text_field :person,:name%></p><br/>
 <p><label for="person_picture">图片</label><br/>
 <%=file_field 'person','photo'%></p>
 <%=submit_tag "创建"%>

show.rhtml:
<p>
  <label for="person_name">姓名:</label>  
  <a href="<%=@picture_path %>" target="_blank">
  <%= @person.name %></a>    
</p>
<p>
  <label for="person_picture">相片:</label>
  <% if not @person.picture.empty? %>
    <%= image_tag(@picture_path) %>
  <% end %>
</p>


解释一下:我要用用户在表单中提交的name作为上传文件的文件名,这时会遇到编码的问题。一开始没有用iconv,结果name为中文的时候会出现无效字符的问题。因此我在make_file_name(name.to_s)name用to_s转换成字符串,后来发现有的中文可以,有的不可以,报错误参数。而且文件名是乱码。后来使用iconv,代码中需要注意的是:person.rb中conv = Iconv.new("GBK","utf-8")这一句,这样上传的文件名才不会是乱码。
另外一个问题就是model类中如何读取表单中的值。make_file_name(name.to_s)这样就可以,表单是<%=text_field :person,:name%>,用这里的属性name做参数就可以,原来还想着从控制器中读出,再穿过来,看来不用。
论坛首页 入门技术版

跳转论坛:
Global site tag (gtag.js) - Google Analytics