使用Rails实现文件上传

来源:互联网 发布:硬笔书法网络直播课 编辑:程序博客网 时间:2024/05/16 11:48

下面开始介绍使用Rails实现文件上传

从View开始:

我们要接受图片,使用的是<input type="file"...>这样的标签,但是注意,含有这样标签的form,在提交以后会产生一种叫做multipart/form-data 这样的POST message,所以我们需要设置一下<form>标签.

 

<%=start_form_tag ({:action=>"upload"},:multipart=>true )%>

<input type="file" name="file[file]">

<%=end_form_tag%>

 

自然你也可以使用helper method来输出 input 标签

 

进入Model:

这一部分是可以放在controller里面(技术上可以),但是MVC构架告诉我们,这样做是不合理的,因为我把保存文件到指定文件夹的工作交给Model(没有对应的表的model)

 

建立一个文件:file.rb放在Model下面

class MyFile < ActiveRecord::Base

    def file=(file_field)    # 这是有特殊含义的

        File.open("#{RAILS_ROOT}/myfile", "wb+") do |f|
            f.write(file_field.read)
        end

    end

end

 

上面的RAILS_ROOT表示Rails app的路径的常量,rails app自动产生的一个常数,file= 给Rails一个假想,让rails以为Files表中有一个file属性,这样,我们就可以传递一个以file为key的value过来,因为 Rails中update_attriubtes,save,new等,都可以使用一个hash作为argument.下面会见到如何使用.

另外重点说明wb+,我们不能使用w,比如用wb+,假如使用w上传图片会:

因为读取方式"w",破坏了二进制文件,我们使用"wb"(或者"wb+"),使用二进制模式(binary mode)打开文件,文件就不会遭到破坏

 

写Controller:

class UploadController < ApplicationController

    def upload

        unless request.get?

            file = MyFile.new(params[:file])    # 自动调用 File 里面的file= method

            if file.save

            # 成功的操作

            else

            # 失败的操作

            end

        end

    end

end

 

 

还需要更多:

前面说过,通过form可以发送一种特殊的POST message,叫做multipart/form-data,这时候,我们在提取<input type="file"...>中的内容时,它实际上一个从硬盘提取到内存的过程,这个过程把文件保存到了一个TempFile的类对象中 (object),TempFile在文档中描述是这样的 Class: Tempfile < DelegateClass(File),因此我们可以使用一些方法,来帮作我们更好的进行文件存储操作:

 

如上,我们通过params[:file][:file]得到的就说一个TempFile object,重要的method:

original_filename获得文件的名字content_type得到文件的类型read读取文件中的数据(从硬盘上读取到内存中)write写文件(把内存中数据写到硬盘中)length获取文件长度

 

 

在目前(今天是06-8-24)最新版本的RoR中,original_filename 形如: 17.gif 这很方便我们使用,假如要判断上传是不是图片就用 content_type, 结果的到形如: image/gif ,不论是什么格式的图片都是image/*** 那么可以在model中使用valide验证数据,这也是为什么把保存文件部分放入model中,因为model对数据可以进行有效的验证


转自:http://caoshouying.blog.163.com/blog/static/56948484201011753731772/

0 0