Carrierwave:文件名/store_dir 中的文件哈希和模型 ID

标签 carrierwave

我在 Rails 4 项目中使用carrierwave,文件存储用于开发和测试,雾存储(用于存储在Amazon S3上)用于生产。

我想用这样的路径保存我的文件:
/model_class_name/part_of_hash/another_part_of_hash/hash-model_id.file_extension
(例如:/images/12/34/1234567-89.png 其中 1234567 是文件内容的 SHA1 哈希值,89 是数据库中关联图像模型的 id)。

到目前为止我尝试过的是:

class MyUploader < CarrierWave::Uploader::Base

  def store_dir
    "#{model.class.name.underscore}/#{sha1_for(file)[0..1]}/#{sha1_for(file)[2..3]}"
  end

  def filename
    "#{sha1_for(file)}-#{model.id}.#{file.extension}" if original_file
  end

  private

    def sha1_for file
      Digest::SHA1.hexdigest file.read
    end

end

这不起作用,因为:
  • 调用 model.idfilename 不可用
  • file 在调用 store_dir 时并不总是可用

  • 所以,来到 我的问题 :
  • 是否可以在 filename 中使用模型 ID/属性? This link 说不应该这样做;有没有办法解决它?
  • 是否可以在 store_dir 中使用文件内容/属性?我没有找到这方面的文档,但到目前为止我的经验说“不”(见上文)。
  • 您将如何实现文件/目录命名以尽可能接近我在开头概述的内容?
  • 最佳答案

  • 在创建时在文件名中包含 id 可能是不可能的,因为文件名存储在数据库中但 id 尚不可用。一个(公认相当极端的)解决方法是在创建时使用临时值,然后 after_commit on: :create ,移动文件并更改数据库中的名称。可以使用 after_create 对此进行优化。 ,但我会把它留给你。 ( This 是carrierwave 实际上传文件的地方。)
  • 直接在 store_dir 中包含文件属性不可能,因为 store_dir用于计算urlurl需要知道 sha1,这需要访问文件,这需要知道 url 等。解决方法很明显:在模型的数据库记录中缓存您感兴趣的属性(在本例中为 sha1),并在 store_dir 中使用它.
  • id-in-filename 方法的更简单的变体是使用一些其他值,例如 uuid,并将该值存储在数据库中。有一些注释here .
  • 关于Carrierwave:文件名/store_dir 中的文件哈希和模型 ID,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18460686/

    相关文章:

    ruby-on-rails - Ruby on Rails CarrierWave gem 是否可以与 Ajax 配合使用?

    ruby-on-rails - 重命名现有的 CarrierWave 文件

    ruby-on-rails - 载波的多个默认图像

    ruby - 重新创建版本!使用 wiki 中规定的唯一文件名方法

    ruby-on-rails - Rails 4 - Carrierwave 图像未上传

    ruby-on-rails - 将 FFMPEG 屏幕截图输出文件保存到变量

    ruby-on-rails - nested_form gem : wrong number of arguments (4 for 3)错误

    ruby-on-rails - Ruby block 语法错误

    ruby-on-rails - Capistrano 和 Carrierwave

    ruby-on-rails - 如何使用 Carrierwave 以编程方式生成 PDF 并将其保存在 S3 上?