Paperclip在保存后重命名文件

fiv*_*six 18 ruby ruby-on-rails paperclip

如何在上传和保存文件后重命名文件?我的问题是我需要自动解析有关文件的信息,以便提出文件应该像我的应用程序一样保存文件名,但我无法访问生成文件名所需的信息,直到记录为止.模型已保存.

Voy*_*yta 24

例如,如果您的模型具有属性图像:

has_attached_file :image, :styles => { ...... }
Run Code Online (Sandbox Code Playgroud)

默认情况下,papepclip文件存储在/ system /:attachment /:id /:style /:filename中.

因此,您可以通过重命名每个样式然后更改数据库中的image_file_name列来完成它.

(record.image.styles.keys+[:original]).each do |style|
    path = record.image.path(style)
    FileUtils.move(path, File.join(File.dirname(path), new_file_name))
end

record.image_file_name = new_file_name
record.save
Run Code Online (Sandbox Code Playgroud)


Fot*_*ios 23

看过回形针插补吗?

如果它是你可以在控制器中找到的东西(在它被保存之前),你可以使用控制器,模型和插值的组合来解决你的问题.

我有这个例子,我想根据它的MD5哈希来命名文件.

在我的控制器中我有:

params[:upload][:md5] = Digest::MD5.file(file.path).hexdigest
Run Code Online (Sandbox Code Playgroud)

然后我有一个config/initializers/paperclip.rb:

Paperclip.interpolates :md5 do|attachment,style| 
  attachment.instance.md5
end
Run Code Online (Sandbox Code Playgroud)

最后,在我的模型中,我有:

validates_attachment_presence :upload
has_attached_file :upload,
  :path => ':rails_root/public/files/:md5.:extension',
  :url => '/files/:md5.:extension'
Run Code Online (Sandbox Code Playgroud)


Jar*_*red 18

要添加到@ Voyta的答案,如果您使用带回形针的S3:

(record.image.styles.keys+[:original]).each do |style|
  AWS::S3::S3Object.move_to record.image.path(style), new_file_path, record.image.bucket_name
end

record.update_attribute(:image_file_name, new_file_name)
Run Code Online (Sandbox Code Playgroud)

  • 不应该是`record.image.s3_object.move_to`而不是`AWS :: S3 :: S3Object.move_to`?move_to是AWS :: S3 :: S3Object的实例方法,而不是类方法. (3认同)
  • 它现在被称为'rename_to'或'move_to' (2认同)

Pab*_*ero 6

我的头像图像以用户slug命名,如果他们更改了他们的名字我也必须重命名图像.

这就是我使用S3和回形针重命名我的头像图像的方法.

class User < ActiveRecord::Base
  after_update :rename_attached_files_if_needed

  has_attached_file :avatar_image,
    :storage        => :s3,
    :s3_credentials => "#{Rails.root}/config/s3.yml",
    :path           => "/users/:id/:style/:slug.:extension",
    :default_url    => "/images/users_default.gif",
    :styles         => { mini: "50x50>", normal: "100x100>", bigger: "150x150>" }

  def slug
    return name.parameterize if name
    "unknown"
  end


  def rename_attached_files_if_needed
    return if !name_changed? || avatar_image_updated_at_changed?
    (avatar_image.styles.keys+[:original]).each do |style|
      extension = Paperclip::Interpolations.extension(self.avatar_image, style)
      old_path = "users/#{id}/#{style}/#{name_was.parameterize}#{extension}"
      new_path = "users/#{id}/#{style}/#{name.parameterize}#{extension}"
      avatar_image.s3_bucket.objects[old_path].move_to new_path, acl: :public_read
    end
  end
end
Run Code Online (Sandbox Code Playgroud)


rna*_*aud 5

并添加另一个答案,这是我用于 S3 重命名的完整方法:

  def rename(key, new_name)
    file_name = (key.to_s+"_file_name").to_sym
    old_name = self.send(file_name)
    (self.send(key).styles.keys+[:original]).each do |style|
      path = self.send(key).path(style)
      self[file_name] = new_name
      new_path = self.send(key).path(style)
      new_path[0] = ""
      self[file_name] = old_name
      old_obj = self.send(key).s3_object(style.to_sym)
      new_obj = old_obj.move_to(new_path)
    end
    self.update_attribute(file_name, new_name)
  end
Run Code Online (Sandbox Code Playgroud)

使用: Model.find(#).rename(:avatar, "test.jpg")