2008-11-15 48 views
3

我正在研究添加一个函数到我的基于Rails的Intranet站点的可行性,允许用户上传文件。Rails非图像文件上传到数据库而不使用服务器端临时文件?

两个目的: 我的用户在地理上广泛分布,并且链接到共享网络存储上的文档并不总是能够正常工作(不同的地址,DNS条目以及我的控制或兴趣之外的东西),所以我正在考虑提供面向数据库的替代品。 我们有许多文件可以从客户端解析数据。我宁愿能够把它推到服务器上。

我看过attachment_fu,回形针和另外一个(忘记名字!),所有这些看起来都很像图像,尽管attachment_fu至少可以在没有图像处理库的情况下工作,谢天谢地。

最大的问题是我的服务器不允许我的应用程序在本地写文件,而且这些插件似乎都想创建一个Tempfile。

的问题(最终!)

是否有上传的二进制数据,并在内存中处理它和/或存储它作为一个BLOB没有任何服务器端的文件保存一个合理的方式?

或者我应该放弃文件分发的想法,让用户在可能的情况下复制并粘贴文本框的次佳选项?

(最近我能找到的SO是this这并不能真正帮助)

回答

1

最大的问题是我的服务器不允许我的应用程序在本地写文件,而且这些插件似乎都想创建一个Tempfile。

是的,或者你根本无法上传文件。

如果上传的文件大于15k左右,Rails本身会创建临时文件。

<%= f.file_field :file %> 
.... 
file_param = params[:upload][:file] 

只要你上传的东西比15K大不久,params[:upload][:file]将是一个ActionController::UploadedTempFile

有什么区别? Rails可能会将它的临时文件写入全局临时目录(每个人都可以写入),但插件可能会尝试写入RAILS_ROOT/tmp,这是服务器不允许的。好消息是,你可以将这些东西配置为使用不同的临时目录,以便他们可以编写临时文件,而且应该都可以工作。

例如,attachment_fu's default temp path is under rails root.。你应该能够改变这样的:

Technoweenie::AttachmentFu.tempfile_path = Dir::tmpdir 

** PS:拉文件数据直出则params的并将其放入数据库中仍可能是最好的一段路要走。我个人不喜欢attachment_fu,因为他们试图做太多的事情,但无论哪种方式,了解整个上传文件/临时文件如何在rails中工作是非常有用的:-)

+0

啊。所以它确实如此。当然,我的测试上传文件是13.5K ... 我想知道服务器(gulp)会发生什么。 – 2008-11-20 13:54:24

1

HowTo为Rails包括如何直接上传到数据库中的部分(靠近页面末尾)。该部分有些搞砸了,但其要点是,您只需将上传的文件内容读入ActiveRecord对象的BLOB字段并保存为正常。由于我不知道如何在应用程序中使用该文件,因此我无法就如何在数据库中使用该文件给出任何建议,但在HowTo中也有一段关于从数据库中下载的部分。

查看是否可以获得写入服务器上的单个目录(可能位于您的Web应用程序文件夹中)的权限可能会更容易。

+0

关于许可的事情 - 它已经被要求了,但是我们的IT人员可以花费很长时间来处理这样的事情。个月。许多个月。你不会相信建立一个数据库实例需要多长时间。那么,也许你会。 – 2008-11-16 11:01:46

7

您可以从params对象读取数据,并直接写入模型。

例如,您可以使用这种形式。

<% form_for :upload, :url => {:action=>:upload}, :html=>{:multipart=>true} do |f| %> 
    <%= f.file_field :file %> 
    <%= f.submit 'Upload' %> 
<% end %> 

然后你可以很容易地得到原始文件名和二进制数据。

class TestController < ApplicationController 

    def upload 
    file_param = params[:upload][:file] 
    filename = file_param.original_filename 
    filedata = file_param.read 

    @data = UploadedFile.create(:name => filename, :data => filedata) 

    render :text => "created #{@data.id}" 
    end 

end 

当然你的模型需要有正确的列。

class CreateUploadedFiles < ActiveRecord::Migration 
    def self.up 
    create_table :uploaded_files do |t| 
     t.string :name 
     t.binary :data 
     t.timestamps 
    end 
    end 

    def self.down 
    drop_table :uploaded_files 
    end 
end 

希望这有助于!

+0

我差点把它 - 我错过了params上的双引用[:upload] [:file] 它的作品,应该让事情变得有趣!谢谢。 – 2008-11-17 10:20:20

0

所以这段代码在我的控制器:

def upload 
    file_content = params[:upload][:file] 
    render :text => [ 
     [:original_path, :content_type, :local_path, :path, :original_filename].collect {|m| file_content.send(m)}, 
     file_content.class, 
     file_content.size.to_s].flatten.join("<br/>") 
    end 

给出了这样的一个更小的文件:

b_wib.xls 
application/vnd.ms-excel 


b_wib.xls 
ActionController::UploadedStringIO 
13824 

这对于一个较大:

a_wib.xls 
application/vnd.ms-excel 
/tmp/CGI.10029.1 
/tmp/CGI.10029.1 
a_wib.xls 
ActionController::UploadedTempfile 
27648 

......这与Orion所描述的完全相同。

0

为别人读这只是同时保存文件/ IO params中的数据库是一个很好的解决方案(为什么问题复杂化)回形针,我会怀疑attachment_fu,都没有具体的形象。由于上传图像和调整大小非常常见Paperclip附带一个处理器来调整图像大小,但默认情况下它未启用,您可以轻松添加自己的处理器。

相关问题