Paperclip - rename file before saving
Asked Answered
A

3

16

I use this method for renaming the image before the saving:

  def rename_avatar
    self.avatar.instance_write :file_name, Time.now.to_i.to_s
  end

  before_post_process :rename_avatar

The image is renamed by the current time, but there's not added the file type, instead of 1334487964.jpg is saved only 1334487964..

What I missing there? I thought :file_name contains only the file name - without the file type

Ara answered 23/4, 2012 at 12:44 Comment(0)
A
24

This is the way how I fix my issue:

  def rename_avatar
    #avatar_file_name - important is the first word - avatar - depends on your column in DB table
    extension = File.extname(avatar_file_name).downcase
    self.avatar.instance_write :file_name, "#{Time.now.to_i.to_s}#{extension}"
  end
Ara answered 30/4, 2012 at 12:32 Comment(1)
This solution works ok, except for the fact if you are editing the record. in my case, i have 3 attachments, photo, certificate1, certificate2, if i change the photo, i have to upload certificates again because when the routine goes to callback "before_post" it records a new and inexisting file name on DB. Do you have a solution for this? Thanks! ;)Brimful
E
2

Since Paperclip recommends using interpolates, this link can help you the best. https://wyeworks.com/blog/2009/7/13/paperclip-file-rename

Egalitarian answered 28/4, 2017 at 9:48 Comment(1)
@drmwndr, too late to the party but this can help you fix your issue.Egalitarian
F
1

I have tried all the previous solutions, it doesn't work with me very well... However, I have created this solution and it works with me on all the styles

  attr_accessor :avatar_update_file_name
  has_attached_file :avatar,
                    :styles => {
                      :medium => "288x288#",
                      :small => "150x150#",
                      :thumb => "48x48#"
                    },
                    :path => YOUR_PATH + ":style/:basename.:extension",
                    :url => YOUR_PATH + ":style/:filename",
                    preserve_files: true


  process_in_background :avatar, only_process: [:medium, :small, :thumb, :original]
  after_save :rename_avatars

  def rename_avatars
    if self.avatar_update_file_name == true
      new_file_hash = "#{SecureRandom.urlsafe_base64}"
      new_file_name = ""
      (self.avatar.styles.keys+[:original]).each do |style|
        path = avatar.path(style)
        if(File.file?(path))
        File.chmod(0777, File.dirname(path))
        new_file_name = "#{new_file_hash}.#{extension}"
        FileUtils.move(path, File.join(File.dirname(path), new_file_name))
        end
      end
      self.avatar_update_file_name = false
      self.avatar_file_name = new_file_name
      self.save!
    end
  end

This will loop on your style every time you save your object and you set avatar_update_file_name = true for one time per object call and it will update your records

for example, your class name is "Avatars"

avatar = new Avatars
#... upload and work with files
avatar.avatar_update_file_name = true
avatar.save!

This will invoke the make the file rename charm!

Note: you can use this "before_save" but the problem is the paperclip might not create this files on the filesystem

Hope this will helps

Favors answered 23/7, 2018 at 9:48 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.