I need unique filenames for my files.
def filename
"#{SecureRandom.urlsafe_base64}.gif"
end
This saves a file such as this:
ylGP48WxZXOY2OQ_x9dxAA.gif
however its respective field in the database to be saved like this:
jED48PRNz0asZzwYQXzecw.gif
I think what's happening is that Carrierwave is calling the file_name
function when it's writing the file and when its saving the instance in the database, resulting in urlsafe_base64 being called twice and creating two different strings. It works perfectly when I've hardcoded a name as a test.
So how can stop this? I know it's outrageous to ask, but how can I make Carrierwave use the same randomly generated filename in the database and when writing the file? I seriously think this should be considered a bug.
Since two files cannot have the same name, if you enter a folder name that was previously used, the system will have a suffix addition to its name in the form of (k) , where, k is the smallest positive integer such that the obtained name remains unique.
Uniqueness. Within a single directory, filenames must be unique. Since the filename syntax also applies for directories, it is not possible to create a file and directory entries with the same name in a single directory. Multiple files in different directories may have the same name.
This is one option:
def filename
random_string
end
protected
def random_string
@string ||= "#{SecureRandom.urlsafe_base64}.gif"
end
I agree carrierwave could a be a tad more intuitive.
http://ruby-doc.org/stdlib-2.4.0/libdoc/tempfile/rdoc/Tempfile.html
Tempfile
A utility class for managing temporary files. When you create a Tempfile object, it will create a temporary file with a unique filename. A Tempfile objects behaves just like a File object, and you can perform all the usual file operations on it: reading data, writing data, changing its permissions, etc. So although this class does not explicitly document all instance methods supported by File, you can in fact call any File instance method on a Tempfile object.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With