Rails 3 - Tempfile路径?

20

我有如下内容:

attachments.each do |a|
   Rails.logger.info a.filename
   tempfile = Tempfile.new("#{a.filename}", "#{Rails.root.to_s}/tmp/")
   Rails.logger.info tempfile.path
end

附件来自Paperclip。

这是输出结果:

billgates.jpg
/Users/bhellman/Sites/cline/tmp/billgates.jpg20101204-17402-of0u9o-0

为什么文件名最后会附加上 20101204-17402-of0u9o-0 ,这会导致使用 paperclip 等工具时出现问题。有人见过这种情况吗?我真的不知道是什么东西在做这件事情。

谢谢。

更新 Paperclip: Github 上的 Paperclip

a 是附件文件。

tempfile = Tempfile.new("#{a.filename}", "#{Rails.root.to_s}/tmp/")
tempfile << a.body
tempfile.puts
attachments.build(
    :attachment => File.open(tempfile.path)
)

为什么不直接使用File.new而不是Tempfile.new? - Ryan Bigg
好问题。它需要与Heroku兼容,他们的文档说要使用tempfile? - AnApprentice
如果有冲突,File.New 不会出问题吗? - AnApprentice
5个回答

27

为了确保您的临时文件具有正确的扩展名,在保存后不需要尝试更改它,请使用以下代码:

file = Tempfile.new(['hello', '.jpg'])

file.path # => 类似于:"/tmp/hello2843-8392-92849382--0.jpg"

更多信息请参见:http://apidock.com/ruby/v1_9_3_125/Tempfile/new/class


4

Tempfile.new的第一个参数只是一个基本文件名。为了确保每个Tempfile都是唯一的,字符会附加在文件末尾。


谢谢John,但这会破坏Paperclip,而Paperclip需要使用:attachment => File.open(tempfile.path)。我如何将该临时文件发送到Paperclip,而不附加任何随机字符串作为文件名?谢谢。 - AnApprentice
我不确定你想用Paperclip做什么。你是想改变默认路径吗? - drummondj
这是我现在在Paperclip中的代码::attachment => File.open(tempfile.path)。问题在于,当Paperclip将文件上传到S3时,它使用临时文件名。因此,在发送给Paperclip之前,需要清理/更正文件名。 - AnApprentice
你能否将临时文件数据发送给Paperclip,并告诉它要使用的文件名?类似这样::attachment => send_data File.open(tempfile.path), :filename => "thefile.extttt" - AnApprentice
你能否发布一下使用了“:attachment”选项的代码?我对这个选项不熟悉。 - drummondj
我建议您使用File.new,并确保文件名不存在。使用"#{Rails.root.to_s}/tmp/#{n}/#{a.filename}",其中n是整数。从n = 0开始递增,直到文件不存在。 - drummondj

0
你应该使用Paperclip的API来实现这个功能。
tempfiles = []
attachments.each do |a|
  # use Attachment#to_file to get a :filesystem => file, :s3 => tempfile
  tempfiles << a.to_file
end

tempfiles.each do |tf|
  Rails.logger.debug tf.filename
end

我不理解上面的建议有什么改变?有什么办法可以避免Tempfile给出疯狂的随机文件名? - AnApprentice
我认为你的问题是,当你从存储中拉取文件时,临时文件具有奇怪的文件名。 - yfeldblum
我创建了一个临时文件,然后通过(:attachment => File.open(tempfile.path)将其发送给paperclip来保存附件。就是在这里,paperclip从临时文件中获取文件名。这就是问题所在,因为此时临时文件的文件名末尾包含了所有的随机字符。 - AnApprentice
问题是,将临时文件发送到Paperclip以保存,以一种不具有疯狂文件名的方式保存,而是使用原始文件名,以便Paperclip在S3上正确保存它。这有帮助吗? - AnApprentice

0
attachment = attachments.build(
  :attachment => File.open(tempfile.path)
)

# change the displayed file name stored in the db record here
attachment.attachment_file_name = a.filename # or whatever else you like

attachment.save!

1
尝试过这种方法,但问题在于 S3 上的文件名没有得到更新。只有数据库中的文件名被更新了,这实际上使链接无效,导致文件丢失。 - AnApprentice
1
要么在保存记录之前更改文件名,要么不要将临时文件中的文件名包含在S3可见的文件名中。 - yfeldblum

0
我发现处理这个问题的最佳方法是在Paperclip属性中指定文件扩展名。例如:
has_attached_file :picture,
  :url => "/system/:hash.jpg",
  :hash_secret => "long_secret_string",
  :storage => :s3,
  :s3_credentials => "#{Rails.root}/config/s3.yml"

请注意,:url 声明为 '.jpg' 而不是传统的 .:extension
祝你好运!

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接