通常,在rails中处理文件上传,我们会这么做,在view中生成相应html tag:
<input name="my_uploaded_file" type="file">
然后,在controller中,我们可以通过params[:my_uploaded_file]得到上传文件,进行相应处理。
假如,现在作为controller的开发人员,我不知道view开发人员将input的name设置成什么?那应该如何处理呢?可能这个例子有些极端,绝大部分时候不存在这个问题。那再假如,现在我们要利用rails实现一个api,该api的功能是实现文件上传,rails后台得到该文件,并进行处理。由于这是一个开放api,用户可能通过jsp,rails,php,甚至桌面程序等来访问我们的api,这个时候又该如何处理呢?(当然,你可以在api specification中定死,说,我的地盘我做主,你们要使用我的api上传文件,form-data的name必须是XXX!)
在asp.net中倒是可以很简单的解决这个问题,我记得asp.net中的form提供了一个参数,开发人员可以直接访问该参数得到此form中所有上传的文件,而不必管name是什么。但是在rails中,似乎没有这一机制(如果是我疏忽,望知情同学告知!)。不过,现在稍加修改,rails也同样能象asp.net那样处理上传文件。
首先,我先贴出解决方案,为方便起见,在environment.rb中加入如下代码:
module ActionController
class AbstractRequest
class << self
alias_method :_original_read_multipart_, :read_multipart
def read_multipart(body, boundary, content_length, env)
params = _original_read_multipart_(body, boundary, content_length, env)
file_data = params.values.dup.flatten.select do |form_data|
form_data.respond_to?(:original_path) && !form_data.original_path.blank?
end
params.merge!({"file_data[]" => file_data})
end
private :_original_read_multipart_, :read_multipart
end
end
end
我先大致解释下这段代码:在view中的某个form中,当你加入{:multipart => true}参数,rails会调用AbstractRequest中的私有类方法read_multipart,得到form中所有的参数。所以,我的解决方案就是截获此方法,调用原始版本后,遍历form中的所有值,将所有上传的文件放到一个file_data中去,塞回params中。这样,在controller中,就可以通过params[:file_data]得到form中所有上传文件进行处理,而并不用理会input的name到底是什么。这样做,我们甚至可以处理这种情况:
<input name="same_name" type="file">
<input name="same_name" type="file">
就算这两个input的名字相同,通过file_data,仍然可以得到两个文件。这样,controller得到上传文件的代码便独立了,和view没有任何关系,你爱咋写name都行。另外,这行代码有两个地方值得注意:
params.merge!({"file_data[]" => file_data})
1. 关于key,不能想当然的用:file_data[]。因为rails内部处理参数的时候,调用了key.include?,所以,使用Symbol必然出错。
2. [] 是必须的,否则rails不能将所有的上传文件塞到一个数组中去,这样,在controller中,你将只能通过file_data得到其中一个文件。
另外,上述代码是基于rails 2.0.2。加入你目前正在使用rails 1.*。则可以使用如下代码实现相同的功能:
class CGI #:nodoc:
module QueryExtension
alias_method :_original_read_multipart_, :read_multipart
def read_multipart(boundary, content_length)
params = _original_read_multipart_(boundary, content_length)
file_data = params.values.dup.flatten.select do |form_data|
form_data.respond_to?(:original_path) && !form_data.original_path.blank?
end
params.merge!({"file_data[]" => file_data})
end
private :_original_read_multipart_, :read_multipart
end
end
2008.7.19 22:22 星期六
分享到:
- 2008-07-19 22:23
- 浏览 2267
- 评论(2)
- 论坛回复 / 浏览 (1 / 3154)
- 查看更多
相关推荐
在Ruby on Rails框架中,Paperclip是一个非常流行的用于处理文件上传的库。它提供了一种简单而优雅的方式来管理和处理模型中的附件,如图片、文档等。Paperclip与ActiveRecord紧密集成,使得在Rails应用中添加文件...
Rails提供了一种优雅的方式来处理文件上传,包括存储管理、处理和验证。这篇博文“rails 文件上传”可能详细介绍了如何在Rails应用中实现这个功能。 首先,我们需要了解的是`ActionDispatch::Http::UploadedFile`类...
总结起来,Ruby-CarrierWave是一个强大的文件上传解决方案,它在Rails和Sinatra等Ruby Web框架中提供了优雅、可扩展的文件处理能力。通过其灵活的配置和丰富的功能,开发者可以轻松地管理文件上传,同时保持代码的...
例如,Devise用于用户认证,CanCanCan用于授权管理,Paperclip或Carrierwave处理文件上传,Stripe或PayPal集成支付功能,以及各种数据分析和报表生成库等。 总的来说,这个压缩包对于Ruby on Rails的初学者或希望...
10. **社区和生态系统**:Rails拥有庞大的开发者社区,产生了许多优秀的第三方Gem库,如Devise(身份验证),Paperclip(文件上传),Pundit(权限控制)等,丰富了Rails的功能。 Rails 1.0.0的发布标志着Web开发...
例如,Devise用于用户认证,CanCanCan用于授权管理,Paperclip或Carrierwave处理文件上传等。 此外,本书还会介绍Rails的安全实践,包括防止SQL注入、XSS攻击等常见Web安全问题。你将学习如何使用strong parameters...
- **ActiveRecord和引用完整性**:讨论如何在Rails中处理外键约束和其他引用完整性的问题。 - **迁移和种子数据**:说明如何在迁移过程中插入初始数据。 #### ActiveRecord数据验证 - **数据验证概览**:提供数据...
这个例子展示了如何在Rails控制器中处理文件上传和删除。当然,实际应用中可能需要根据具体需求进行更复杂的定制。 总的来说,Ruby-Attache是一个强大的工具,简化了文件上传的处理,同时提供了丰富的功能和高度的...
第九章讨论了 **文件上传** 的实现方式,这是 Web 应用中常见的功能之一。 - **文件上传**: - 实现用户可以上传图片、文档等文件的功能。 - 需要考虑安全性问题,防止恶意文件上传。 - 可以使用第三方服务,如 ...
最后,Rails社区非常活跃,有许多优秀的第三方gem库可以扩展Rails的功能,例如Devise用于用户认证,CanCanCan处理授权,Paperclip或Carrierwave处理文件上传等。通过`gem 'gem_name'`在`Gemfile`中添加gem,然后运行...
ActiveStorage与云存储服务如Amazon S3或Google Cloud Storage集成,方便地处理文件上传、存储和检索。它还提供了一套内置的图像处理工具,如thumbnail生成,以适应不同的展示需求。 3. **验证码生成**:为了防止...
RoR社区活跃,有许多优秀的gem(RoR的扩展库)可供使用,例如Devise用于用户认证,CanCanCan进行权限控制,Carrierwave或Paperclip处理文件上传,Bootstrap gems帮助快速构建响应式界面等。这些gem极大地扩展了RoR的...
Rails社区活跃,拥有大量的gem(相当于其他语言的库或插件),这些gem扩展了Rails的功能,例如Devise用于身份验证,CanCanCan用于授权管理,Pundit用于细粒度的权限控制,Paperclip或Carrierwave处理文件上传,...
Ruby on Rails的社区非常活跃,拥有丰富的插件和gem(Ruby的库包),如Devise用于身份验证,CanCanCan进行权限管理,Carrierwave或Paperclip处理文件上传等。这些gem极大地扩展了RoR的功能,使得开发者可以快速搭建...
Carrierwave提供了一种优雅的方式处理文件上传,同时与MiniMagick配合良好。添加`gem 'carrierwave'`和`gem 'carrierwave-mongoid'`到Gemfile,根据数据库类型(如Mongoid、ActiveRecord等)进行相应的配置。 创建...
Rails社区活跃,有大量的插件和 gems(Ruby的扩展库)可供使用,如Devise用于身份验证,CanCanCan进行权限控制,Paperclip或Carrierwave处理文件上传等。这些gem极大丰富了Rails的功能,使得开发者可以快速构建复杂...
Rails还提供了许多插件和gem(Ruby的库),如Devise用于用户认证,CanCanCan进行权限控制,以及Paperclip或Carrierwave用于文件上传等。这些工具大大扩展了Rails的功能,书中可能会提及一些常用的gem及其用法。 ...
最后,RoR社区活跃,有大量的gem(Ruby的库或插件)可供使用,例如Devise用于用户认证,CanCanCan进行权限控制,Paperclip或Carrierwave处理文件上传,以及Pundit或Authorizable管理授权等。 通过本教程的...
SWFUpload 是一款开源项目,利用Adobe Flash插件(SWF文件)作为前端界面,提供了一种优雅的方式进行大文件上传,同时还能在上传过程中显示进度条,提高了用户体验。由于Flash的广泛兼容性,SWFUpload在早期的多文件...