`
jn615
  • 浏览: 100485 次
  • 性别: Icon_minigender_1
  • 来自: 火星
社区版块
存档分类
最新评论

ROR 使用 attachment_fu 上传文件

阅读更多

来源:博客园 链接

http://www.cnblogs.com/yank/archive/2009/11/01/attachment.html

 

 

ROR使用attachment_fu上传附件,很方便,但是配置需要研究。

http://github.com/technoweenie/attachment_fu


migration:

class CreateAttachments < ActiveRecord::Migration
  def self
.up
    create_table 
:attachments,:force => true do |t|
      t
.string :filename,:default=>""
      t
.string :content_type,:defaut=>""
      t
.integer :size,:default=>0
      t
.string :org_filename,:default=>""

      t
.timestamps
    end
  end

  def self
.down
    drop_table 
:attachments
  end
end


model:

class Attachment < ActiveRecord::Base
  has_attachment :content_type 
=> [:image,'application/pdf''application/msword''text/plain'],
    :max_size 
=> 4.megabytes, #指定最大值
  :storage => :file_system,  #指定存储方式
  :path_prefix => "/public/attachments/#{Time.now.year}/#{Time.now.month}/#{Time.now.day}/"

  validates_as_attachment

end


view:

<form name="upload" action="/attachments/create" method="post" ENCTYPE="multipart/form-data" >
  
<% if protect_against_forgery? %>
    
<input type="hidden" name="authenticity_token" value="<%= form_authenticity_token %>" >
  
<% end %>
  
<p><input name="attach" type="file" />
    
<input id="submit" name="submit" type="submit"value="上传"/>
  
</p>
</form>


controller:

def create
    @attachment 
= Attachment.new(:uploaded_data =>params[:attach])
    respond_to do 
|format|
      
if @attachment.save!
        flash[:notice] 
= 'Attachment was successfully created.'
        format.html { redirect_to(@attachment) }
        format.xml  { render :xml 
=> @attachment, :status => :created, :location => @attachment }
      
else
        format.html { render :action 
=> "new" }
        format.xml  { render :xml 
=> @attachment.errors, :status => :unprocessable_entity }
      end
    end
  end

 

attachment使用起来很方便,但是其配置比较麻烦,主要是readme文档写的不够全面。所以就会出现一些奇怪的问题。

<1>问题1,其文件名莫名多了几级文件目录。如:/0000/0006/

#文件名

/attachments/2009/10/30/0000/0006/Lighthouse.jpg


但是我并没有定义余下的目录“/0000/0006/”,这并不是我想要,为什么会出现呢?

 

原因:
一个目录下的文件是有限的,所以,作者采用了一种机制,使得文件分多个目录进行存储,在这里用到了id,如果id是integer,会自动将id拆分为两个,例如:id=9,则其存储即为:/0000/0009/。具体大家可以参照:attachment_fu/lib/attachment_fu/bakends/file_system_backend.rb文件full_filename即为文件存储的全路径,处理分区的方法即为:partitioned_path,上面有陈述,可以细细看看。

解决方法:

如果你不需要这种分目录的机制,

一种方法是重写full_filename,

一种就是直接在has_attachment里面加入:partition => false 验证即可。


现在的目录就可以完全操控了。

Attachment_fu will delete them automatically.

参照:http://9esuluciano.iteye.com/blog/137056

 

<2>在上传的时候,偶尔会出现一个验证错误:

Validation failed: Size is not included in the list

 

c:/ruby/lib/ruby/gems/1.8/gems/activerecord-2.3.4/lib/active_record/validations.rb:1090:in `save_without_dirty!'
c:/ruby/lib/ruby/gems/1.8/gems/activerecord-2.3.4/lib/active_record/dirty.rb:87:in `save_without_transactions!'
c:/ruby/lib/ruby/gems/1.8/gems/activerecord-2.3.4/lib/active_record/transactions.rb:200:in `save!'
c:/ruby/lib/ruby/gems/1.8/gems/activerecord-2.3.4/lib/active_record/connection_adapters/abstract/database_statements.rb:136:in `transaction'
c:/ruby/lib/ruby/gems/1.8/gems/activerecord-2.3.4/lib/active_record/transactions.rb:182:in `transaction'
c:/ruby/lib/ruby/gems/1.8/gems/activerecord-2.3.4/lib/active_record/transactions.rb:200:in `save!'
c:/ruby/lib/ruby/gems/1.8/gems/activerecord-2.3.4/lib/active_record/transactions.rb:208:in `rollback_active_record_state!'
c:/ruby/lib/ruby/gems/1.8/gems/activerecord-2.3.4/lib/active_record/transactions.rb:200:in `save!'
D:/Project/RubyProjects/attachment_test/app/controllers/attachments_controller.rb:46:in `create'
D:/Project/RubyProjects/attachment_test/app/controllers/attachments_controller.rb:45:in `create'

原因与解决方案:

它models配置中的:min_size如果不设置位为0,在windows环境下,由于文件处理过程相对较长,所以取不到文件的大小,导致文件大小校验失败,只有把:min_size设为0,校验可以通过。

<3>文件重命名

在存储文件的时候,如果是中文名,经常出错,需要进行重命名。解决方案如下:

 

Code
  protected
  before_save :assign
  
#功能:重新命名、记录存储地址
  #流程:
  #1、记录原始文件名
  #2、重新命名
  #3、记录相对地址
  def assign
    self.org_filename 
= self.filename
    self.filename 
= Time.now.strftime('%Y%m%d-%H%M%S'+ "." + self.filename.split('.')[1]
    self.relative_url 
= self.public_filename
  end

 

<4>public_filename并非存储路径,public_filename是根据path_prefix和filename拼出来的。

如果指定的path_prefix的是固定的,public_filename就是文件的存储路径,

如果path_prefix是变量,就像我上面设置的随时间的改变而改变,那么public_filename就不能标识文件的存储路径,就需要定义一个新的字段来存储。

<5>如果上传中文名的文件,你会看到存储的文件名类似于“____.jpg”

原因:attachment_fu在对文件名进行了限制处理。

在attachment_fu.rb文件中有一个方法:

 

def sanitize_filename(filename) return unless filename returning filename.strip do |name| # NOTE: File.basename doesn't work right with Windows paths on Unix # get only the filename, not the whole path name.gsub! /^.*(\\|\/)/, '' # Finally, replace all non alphanumeric, underscore or periods with underscore name.gsub! /[^A-Za-z0-9\.\-]/, '_' end end
解决方法:

 

如果为了记录中文

1、修改此方法,注释掉:name.gsub! /[^A-Za-z0-9\.\-]/, '_'

2、在上传直接记录原始文件名

 

@attachment = Attachment.new(:uploaded_data =>params[:attachment]) @attachment.org_filename = params[:attachment].original_filename

分享到:
评论

相关推荐

    ROR 文件的上传与下载

    ### ROR 文件的上传与下载:深入解析与实践 在Ruby on Rails(简称ROR)框架下,处理文件的上传与下载是一项常见的需求,尤其是在构建包含媒体内容的应用程序时。本文将基于给定的文件信息,详细阐述如何在Rails...

    ror_invoicing_frontend

    ror_invoicing_frontend项目设置yarn install编译和热重装以进行开发yarn serve编译并最小化生产yarn build整理和修复文件yarn lint自定义配置请参阅。

    ROR_shopping_microservice:用Sinatra制成

    5. **文件结构**: "ROR_shopping_microservice-main"这个文件名可能表示的是项目的主要代码库或者分支。在实际项目中,通常会包含`Gemfile`(管理Ruby依赖)、`config.ru`(Rack配置文件)、`app.rb`(Sinatra应用主...

    BCGSoft[1].Professional.Editor.v6.75-ROR.ZIP_BCGSoft

    bcgsoft professional editor + crack file

    ruby_full:RoR_Full_29 :: Ruby_reports

    Ruby_full: RoR_Full_29 :: Ruby_reports 涵盖了全面的Ruby on Rails(RoR)开发中的报告生成技术。Ruby是一种面向对象的编程语言,以其简洁、优雅的语法著称,而Ruby on Rails是基于Ruby构建的一个开源Web应用框架...

    [转]完美的Tree

    这个标题可能是指一个关于如何高效、优雅地实现或使用树结构的教程或者代码分享。 【描述】:虽然描述部分为空,但我们可以推测这篇博文可能详细介绍了如何创建一个“完美”的树结构,可能包括了优化树的操作,如...

    ROR_care_compass

    您的应用程序在README文件中包含诊断。 报告任何问题时,请提供README文件的副本。 如果该应用程序无法正常运行,请并提供诊断信息。Ruby on Rails 此应用程序需要: Ruby 2.1.6 导轨4.2.1 了解有关更多信息。入门...

    ror_skeletal_app

    自述文件该自述文件通常会记录启动和运行应用程序所需的所有步骤。 您可能要讲的内容: Ruby版本系统依赖配置数据库创建数据库初始化如何运行测试套件服务(作业队列,缓存服务器,搜索引擎等) 部署说明...

    ror_blog_app

    自述文件该自述文件通常会记录启动和运行应用程序所需的所有步骤。 您可能要讲的内容: Ruby版本系统依赖配置数据库创建数据库初始化如何运行测试套件服务(作业队列,缓存服务器,搜索引擎等) 部署说明...

    ror_auth_sp21

    自述文件该自述文件通常会记录启动和运行应用程序所需的所有步骤。 您可能要讲的内容: Ruby版本系统依赖配置数据库创建数据库初始化如何运行测试套件服务(作业队列,缓存服务器,搜索引擎等) 部署说明...

    RoR_julia_eg:通过 ZMQ 使用 Julia 链接的 Ruby on Rails Web 应用程序示例

    此示例展示了一种通过 ZMQ 将 Ruby on ... 如果您使用的是其他平台,您将不得不自己谷歌一些安装程序。 要安装 Ruby on Rails,我只需使用 : curl -sSL https://get.rvm.io | bash -s stable --rails 我更喜欢使

    RoR性能优化经验谈

    在本文中,我们将探讨一些RoR性能优化的关键方面,主要基于JavaEye网站在使用RoR过程中积累的实际经验。 首先,RoR性能优化涉及到多个层面,包括应用程序的部署、服务器配置以及代码优化。在部署方面,操作系统的...

    RoR_API_TDD:Udemy的REST API与Ruby on Rails课程

    自述文件 带有TDD的Rails API Udemy的课程带有Ruby on Rails的REST API 您可能要讲的内容: Ruby版本:2.7.0 Rails版本:5.2.4.4 组态 数据库创建 数据库初始化 测试套件:Rspec 服务(作业队列,缓存服务器,...

    ror中文资料

    6. **Gem生态系统**:Ruby有一个庞大的Gem包管理系统,允许开发者轻松安装和使用第三方库,如Devise(身份验证),Paperclip(文件上传)等。 7. **测试驱动开发(TDD)**:RoR鼓励TDD,提供了Rspec、Cucumber等测试...

    ROR安装必备所有架包

    除了`.gem`文件,压缩包中还有`.tar`和`.tgz`格式的文件,它们是归档文件,可能包含源代码或者未打包的库文件。例如,`activerecord-1.15.5.tar`和`activesupport-1.4.4.tgz`可能是为了那些希望查看或修改原始源代码...

    RoR选题方向—源代码

    7. **Gemfile和依赖管理**:RoR使用Bundler管理外部库(称为Gems),Gemfile定义了项目的依赖,`bundle install`会安装所有必要的库。 此外,标签中提到了其他Web开发技术,如AJAX(异步JavaScript和XML),它用于...

    ror

    NULL 博文链接:https://xuxiangpan888.iteye.com/blog/266696

    ror实例

    在压缩包中的`rubyonrails.pdf`文件可能是Rails的官方文档、教程或某位专家的经验分享,通过阅读这个文件,你可以深入理解Rails的工作方式,学习如何创建和管理数据库、编写控制器、搭建路由、构建视图以及进行测试...

    神经网络ror resenet模型

    **神经网络Ror ResNet模型详解** 在深度学习领域,ResNet(残差网络)模型是具有里程碑意义的创新,由He et al.在2015年提出。该模型解决了深度神经网络训练中的梯度消失问题,允许构建非常深的网络结构。而“Ror”...

    .net文件上传

    为了实现这些功能,开发者可能需要使用第三方库,如jQuery File Upload、FineUploader等,它们提供了断点续传和大文件分块上传的支持。此外,自定义实现也是可行的,需要编写服务器端和客户端的代码来处理分块、合并...

Global site tag (gtag.js) - Google Analytics