生成唯一的文件名

时间:2014-04-01 13:19:59

标签: ruby-on-rails carrierwave

我的文件需要唯一的文件名。

def filename
    "#{SecureRandom.urlsafe_base64}.gif"
end

这会保存如下文件:

ylGP48WxZXOY2OQ_x9dxAA.gif

然而,数据库中的相应字段将保存为:

jED48PRNz0asZzwYQXzecw.gif

我认为发生的事情是Carrierwave在编写文件时调用file_name函数以及在数据库中保存实例时导致urlsafe_base64被调用两次并创建两个不同的字串。当我将一个名字硬编码为测试时,它的工作非常完美。

那怎么能阻止这个呢?我知道这一点令人发指,但是如何让Carrierwave在数据库中使用相同的随机生成的文件名并在编写文件时?我认真地认为这应该被视为一个错误。

2 个答案:

答案 0 :(得分:9)

这是一个选择:

  def filename
    random_string
  end   

  protected 

  def random_string
    @string ||= "#{SecureRandom.urlsafe_base64}.gif"
  end

我同意carrierwave可能更直观一些。

答案 1 :(得分:2)

http://ruby-doc.org/stdlib-2.4.0/libdoc/tempfile/rdoc/Tempfile.html

  

将它视为档案

     

用于管理临时文件的实用程序类。当你创建一个   Tempfile对象,它将创建一个具有唯一性的临时文件   文件名。 Tempfile对象的行为就像File对象一样   可以执行所有常见的文件操作:读取数据,写入   数据,更改其权限等。所以虽然这个类没有   显式记录File支持的所有实例方法,你可以在   事实上,在Tempfile对象上调用任何File实例方法。

require 'tempfile'

file = Tempfile.new('foo')
file.path      # => A unique filename in the OS's temp directory,
               #    e.g.: "/tmp/foo.24722.0"
               #    This filename contains 'foo' in its basename.
file.write("hello world")
file.rewind
file.read      # => "hello world"
file.close
file.unlink    # deletes the temp file