`

如果定制attachment_fu上传文件的路径和文件名

    博客分类:
  • RoR
阅读更多

原文出处:http://the.railsi.st/2007/8/21/how-to-customize-attachment_fu-file-names

For uploading files, it's pretty hard to beat attachment_fu. But it can be overkill for smaller projects.

One issue is that attachment_fu uses id partioning. This is a great way to overcome native file system limitations when you have more than 32,000 attachments. By segmenting files into different directories, you can have millions of attachments, if necessary. Empahsis on "if necessary". It usually isn't.

Also, attachment_fu preserves original filenames. While this make sense for many projects, sometimes you need to have control over the naming of attachments.

Since a lot of people use Mike Clark's excellent File Upload Fu tutorial, let's use that as our starting point for customizing file names.

If we complete the tutorial, here's how attachment_fu will store our first image upload:

public/mugshots/0000/0001/chunkybacon.png 
public/mugshots/0000/0001/chunkybacon_thumb.png

Hmmm, not bad. But I'd like to customize things:

  • Images should be stored in public/images/
  • Thumbnails should be organized by size
  • ID partioning (0000/0001/) should be disabled
  • Images should be renamed with the Mugshot id

So let's open up our Mugshot model and tweak it a bit.

class Mugshot < ActiveRecord::Base 
  has_attachment :content_type => :image,
                 :storage => :file_system,
                 :max_size => 500.kilobytes,
                 :resize_to => '320x200>',
                 :thumbnails => { :thumb => '100x100>' },
                 :path_prefix => 'public/images/mugshots'
  validates_as_attachment


  def full_filename(thumbnail = nil)
    file_system_path = (thumbnail ? thumbnail_class : self).attachment_options[:path_prefix]
    case self.thumbnail
    when "thumb"
      File.join(RAILS_ROOT, file_system_path, 'thumb', thumbnail_name_for(thumbnail, self.parent_id))
    else
      File.join(RAILS_ROOT, file_system_path, 'fullsize', thumbnail_name_for(thumbnail, self.id))
    end
  end


  def thumbnail_name_for(thumbnail = nil, asset = nil)
    extension = filename.scan(/\.\w+$/)
    return "#{asset}#{extension}"
  end
end

Now, when we upload an image, it will be stored like so:

public/images/mugshots/fullsize/2.png 
public/images/mugshots/thumb/2.png

How does this work?

Well, first, we customize the :path_prefix value in has_attachment to set the base location of our files.

Second, we override the full_filename method to force attachment_fu to save each thumbnail type into its own directory. This way, all large thumbnails are stored in images/mugshots/fullsize and all small thumbnails are stored in images/mugshots/thumb. (By default, attachment_fu stores all thumbnail sizes for an object in a single directory.)

Lastly, we override the thumbnail_name_for method to customize the filename to our liking... in this case, the file name will consist of the parent mugshot id, plus the original file's file extension.

That's all we need to do... now our files are stored exactly where we want them!

(Thanks to AirBlade Software for showing the way.)

Extra credit

If your attachments belong to another model (like a user), you'll need to use a before filter to associate the parent model id with the thumbnail you wish to store.

before_thumbnail_saved do |record, thumbnail| 
  thumbnail.user_id = record.user_id
end

You'll also need an extra migration to store the parent id. (Don't use the parent_id field... that's reserved by attachment_fu.)

Extra, extra credit

What if you want three sizes? Large (original image), medium, and small?

has_attachment :content_type => :image, 
               :storage => :file_system,
               :max_size => 500.kilobytes,
               :thumbnails => { :small => '100x100>', :medium => '200x200>' },
               :path_prefix => 'public/images/mugshots'
validates_as_attachment


def full_filename(thumbnail = nil)
  file_system_path = (thumbnail ? thumbnail_class : self).attachment_options[:path_prefix]
  case self.thumbnail
  when "small"
    File.join(RAILS_ROOT, file_system_path, 'small', thumbnail_name_for(thumbnail, self.parent_id))
  when "medium"
    File.join(RAILS_ROOT, file_system_path, 'medium', thumbnail_name_for(thumbnail, self.parent_id))
  else
    File.join(RAILS_ROOT, file_system_path, 'large', thumbnail_name_for(thumbnail, self.id))
  end
end
分享到:
评论

相关推荐

    浅析PHP 中move_uploaded_file 上传中文文件名失败

    项目需要上传文件名保持不变,发现上传中文失败:错误如下: move_uploaded_file&#40;public/upload/files/2019/04-17/\开密二次开发.rar&#41;: failed to open stream: Invalid argument 失败的原因大致猜到是...

    彻底解决Asp.net 文件下载时文件名的中文乱码和空格异常全球性技术难题

    彻底解决Asp.net 文件下载时文件名的中文乱码和空格异常全球性技术难题 本文用 C# 代码解决了在目前四种流行浏览器中Asp.net 输出文件流时文件名的空格及中文字符乱码这两个问题。使用本文的代码,你将可以让 IE...

    java导出文件文件名处理

    在Web应用中,当服务器向客户端发送文件时,HTTP协议中会包含一个`Content-Disposition`头,用于指定文件的类型和文件名。通常情况下,这个文件名需要被正确编码,以便能够在各种浏览器环境下正常显示。如果编码不当...

    AT_Attachment_with_Packet_Interface_-_7_Volume_3

    AT_Attachment_with_Packet_Interface_-_7_Volume_3

    上传文件_上传下载_C#上传文件_文件上传.net_

    在.NET开发环境中,C#语言提供了丰富的功能来处理文件上传和下载操作,这对于Web应用程序来说是必不可少的功能。本文将深入探讨C# ASPX.NET中如何实现文件上传与下载,同时介绍如何限制上传文件的格式,确保系统安全...

    attachment_1487958_16b_win64_2017-05-10

    标题中的"attachment_1487958_16b_win64_2017-05-10"很可能是一个软件安装包或更新文件,尤其考虑到它与MATLAB 2016相关。这个文件名包含了几个关键信息:首先,“16b”可能表示这是MATLAB的一个版本号,可能是R2016...

    .net 下载文件.后修改文件名

    - `Content-Disposition`头用于告诉浏览器如何处理文件,"attachment"指示浏览器应将文件作为附件下载,而不是尝试打开。同时,通过`HttpUtility.UrlEncode`对文件名进行编码,防止因特殊字符导致的问题。 - `...

    struts2 中文文件名文件下载

    在处理文件上传和下载时,Struts2可能会遇到一个常见的问题,即中文文件名的乱码问题。这是因为不同的系统和软件对字符编码的支持不同,尤其是涉及到网络传输时,编码的兼容性尤为重要。 在“struts2 中文文件名...

    H_attachment_comprose_matlab_

    总的来说,`H_attachment_comprose.m`文件提供了一个MATLAB解决方案,用于生成不同数量边的方位标志,并且可能包含了一些辅助功能,如图例创建和图形调整,以满足各种绘图需求。在实际使用中,用户只需调用这个函数...

    _storage_emulated_0_android_data_com.tencent.mm_MicroMsg_517174082dbc007f25c5bd836bdd4446_attachment_段润昌_648.wps

    _storage_emulated_0_android_data_com.tencent.mm_MicroMsg_517174082dbc007f25c5bd836bdd4446_attachment_段润昌_648.wps

    566223_ATTACHMENT01_filamentwinding_filament_zip_

    标题中的"566223_ATTACHMENT01_filamentwinding_filament_zip_"似乎是一个文件名,其中包含了关键词"filament winding",这通常是指一种制造复合材料管状或圆柱形结构的技术。该技术涉及将连续纤维(如碳纤维或玻璃...

    【JavaScript源代码】Vue通过阿里云oss的url连接直接下载文件并修改文件名的方法.docx

    在本文档中,我们探讨了如何在Vue.js应用中通过阿里云OSS(Object Storage Service)的URL直接下载文件,并在下载过程中修改文件名。在尝试通过HTML的`&lt;a&gt;`标签直接设置`download`属性来实现重命名失败后,作者选择...

    ATA_AT_Attachment.rar_AT Attachment_ATA_AT_Attachment_ATA接口_WORK

    ATA接口的详细解读,working draft proposed American National Standard for Information Systems - ATA (ATAttachment) 78页

    Java实现文件下载并解决中文文件名乱码

    ### Java实现文件下载并解决中文文件名乱码 在日常的Web开发中,经常会遇到需要让用户下载文件的需求,尤其是在企业级应用中。然而,在实际操作过程中可能会遇到一个常见问题:当文件名包含中文字符时,下载后的...

    文件下载response.setHeader()下载中文文件名乱码问题解决办法.pdf

    文件下载response.setHeader()下载中文文件名乱码问题解决办法 本文主要讨论了文件下载时response.setHeader()下载中文文件名乱码问题的解决办法。该问题是由于 HTTP 消息头中的 Content-Disposition 头字段不正确...

    welogic struts2文件下载中文件名乱码:在tomcat中是好的哦

    在IT领域,特别是Web开发中,处理文件下载时遇到文件名乱码问题是一个常见的挑战,尤其是在不同的服务器环境下,如WeLogic与Tomcat之间的差异。本文将深入探讨在WeLogic服务器中使用Struts2框架进行文件下载时遇到的...

    导出到Excel,并且自定义文件名

    5. 从前端获取用户输入的文件名,设置响应头,例如`Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"` 和 `Response.AddHeader("Content-Disposition", "attachment;...

    sf_attachment_mover

    CSV将包含两列:ParentId查找和文件名。 这是一个示例CSV文件: ParentId 文件路径 001E0000016s7ok test.html 然后,该文件将在匹配的“帐户”记录中插入附件。 但是,如果您没有可访问的Salesforce ID,则还...

    jsp实现文件下载与中文文件名乱码问题解决

    3. 为了读取服务器上的文件并将其输出到客户端,使用了`FileInputStream`和`OutputStream`。通过`fileInputStream.read()`读取文件内容,然后写入到`response.getOutputStream()`,这样浏览器就能接收到文件数据。 ...

    Java应用下载文件功能,输出文件名中的中文乱码

    在Java应用中实现文件下载功能时,经常遇到的一个问题是输出文件名中的中文字符会出现乱码。这主要是因为HTTP协议在传输文件名时,默认使用的是ISO-8859-1编码,而中文字符在此编码下无法正确解析,从而导致乱码的...

Global site tag (gtag.js) - Google Analytics