我需要为我的 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
对模型进行操作来刷新其属性) .