0

我需要为我的 Rails 应用程序版本图像。我使用 Carrierwave 进行文件上传,使用 PaperTrail 进行版本控制。

虽然版本控制似乎工作得很好,但似乎在停用 Carrierwave 的remove_previously_stored_files_after_update配置后,具体化版本并不能很好地发挥作用:在这种情况下,一个简单reload的具体化模型实例不再工作,只有从数据库中显式地重新加载(使用Model.find 123)有效。

我创建了一个演示 Rails 应用程序来演示该问题。

User模型安装了两个上传器:

  • AvatarUploader,更新后删除文件(默认)
  • KeepingFilesAvatarUploader,更新后不会删除文件,使用remove_previously_stored_files_after_update设置为的选项false

代码AvatarUploader

# encoding: utf-8

class AvatarUploader < CarrierWave::Uploader::Base
  storage :file

  def store_dir
    "uploads/#{model.class.to_s.underscore}/#{model.id}/#{mounted_as}"
  end
end

代码KeepingFilesAvatarUploader

# encoding: utf-8

class KeepingFilesAvatarUploader < CarrierWave::Uploader::Base
  storage :file

  def store_dir
    "uploads/#{model.class.to_s.underscore}/#{model.id}/#{mounted_as}"
  end

  configure do |config|
    config.remove_previously_stored_files_after_update = false
  end
end

唯一的区别是remove_previously_stored_files_after_update选项。

这是User模型的代码:

class User < ActiveRecord::Base
  has_paper_trail only: [:name, :avatar, :keeping_files_avatar]
  mount_uploader :avatar, AvatarUploader
  mount_uploader :keeping_files_avatar, KeepingFilesAvatarUploader
end

我写了一些说明意外行为的规范。由于它们的发布时间有点长,请参见此处:

https://github.com/jmuheim/test-carrierwave-papertrail/blob/master/spec/models/user_spec.rb#L20

除了我设置的那个之外,所有规格都通过了pending,这是输出:

  1) User versioning reloading the model after reify sets "keeping_files_avatar" to the original value
     # See http://stackoverflow.com/questions/29624223/papertrail-doesnt-play-nice-with-carrierwave-and-remove-previously-stored-file
     Failure/Error: expect(user.keeping_files_avatar.file.filename).to eq 'original-image.jpg' # This upload field isn'! <<<FAILING LINE>>>!

       expected: "original-image.jpg"
            got: "new-image.jpg"

       (compared using ==)
     # ./spec/models/user_spec.rb:20:in `block (4 levels) in <top (required)>'

Finished in 0.20704 seconds (files took 1.51 seconds to load)
4 examples, 0 failures, 1 pending

让它发挥作用真是太好了。我现在不需要这个功能,但我不想给我的项目增加任何技术债务(尤其是这个可能会导致非常不可预见的问题,因为通常依赖于简单地reload对模型进行操作来刷新其属性) .

4

1 回答 1

0

检查这是否适合您

class User < ActiveRecord::Base
  has_paper_trail only: [:name, :avatar, :keeping_files_avatar]

  mount_uploader :avatar, AvatarUploader
  mount_uploader :keeping_files_avatar, KeepingFilesAvatarUploader

  skip_callback :save, :after, :remove_previously_stored_keeping_files_avatar
end
于 2015-04-24T13:28:30.607 回答