Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Paperclip how to change basename (filename)?

I am trying to change the basename (filename) of photos:

In my model I have:

  attr_accessor :image_url, :basename

  has_attached_file :image,
          :styles => { :original => ["300x250>", :png], :small => ["165x138>", :png] },
          :url  => "/images/lille/:style/:id/:basename.:extension",
          :path => ":rails_root/public/images/lille/:style/:id/:basename.:extension"
before_save :basename
private

  def basename
  self.basename = "HALLLO"
  end

But the filename is not changed at all.

like image 297
Rails beginner Avatar asked Mar 07 '12 18:03

Rails beginner


3 Answers

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.

like image 161
rjkrath Avatar answered Oct 18 '22 08:10

rjkrath


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
like image 34
Arnold Roa Avatar answered Oct 18 '22 08:10

Arnold Roa


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 ;) )

like image 3
Deradon Avatar answered Oct 18 '22 10:10

Deradon