I am trying to change the basename (filename) of photos:
In my model I have:
attr_accessor :image_url, :basename
has_attached_file :image,
Paperclip now allows you to pass in a FilenameCleaner object when setting up has_attached_file
.
Your FilenameCleaner object must respond to call
with filename as the only parameter. The default FilenameCleaner removes invalid characters if restricted_characters
option is supplied when setting up has_attached_file
.
So it'll look something like:
has_attached_file :image,
filename_cleaner: MyRandomFilenameCleaner.new
styles: { thumbnail: '100x100' }
And MyRandomFilenameCleaner will be:
class MyRandomFilenameCleaner
def call(filename)
extension = File.extname(filename).downcase
"#{Digest::SHA1.hexdigest(filename + Time.current.to_s).slice(0..10)}#{extension}"
end
end
You could get away with passing in a class that has a self.call
method rather than an object but this conforms to Paperclip's documentation in Attachment.rb.
I wanted to avoid having to add a before_create
callback to every model with an attachment. I had a look at the source and at the time of this writing it looked sth like:
module Paperclip
class Attachment
...
def assign_file_information
instance_write(:file_name, cleanup_filename(@file.original_filename))
instance_write(:content_type, @file.content_type.to_s.strip)
instance_write(:file_size, @file.size)
end
So you could just patch cleanup_filename
.
module Paperclip
class Attachment
def cleanup_filename(filename)
"HALLLO"
end
end
end
If you are assigning the file directly you can do this:
photo.image = the_file
photo.image.instance_write(:file_name, "the_desired_filename.png")
photo.save
Im doing this to strip whitespaces:
before_post_process :transliterate_file_name
private
def transliterate_file_name
self.instance_variable_get(:@_paperclip_attachments).keys.each do |attachment|
attachment_file_name = (attachment.to_s + '_file_name').to_sym
if self.send(attachment_file_name)
self.send(attachment).instance_write(:file_name, self.send(attachment_file_name).gsub(/ /,'_'))
end
end
end
I hope this will help you.
edit:
In your example:
def basename
self.image_file_name = "foobar"
end
Should do the job. (but might rename the method ;) )