I've got a very strange issue :
During my test, Shrine is destroying the source file of my uploads ! The issue appear in 2.7.0 version, but I don't have problem with 2.5.0...
I'm using rails 5.0.6.
Here is my Factory :
FactoryGirl.define do
factory :hunt do
title Faker::Lorem.word
user { FactoryGirl.create(:user) }
description Faker::Lorem.sentence
follower true
number_of_follower { rand(1..5) }
comment Faker::Lorem.sentence
started_at Time.now + 10.days
finished_at Time.now + 15.days
acceptance_deadline Time.now + 9.days
price { rand(1..100) }
exchange true
address 'test address'
picture { File.open("spec/fixtures/files/picture.jpg") }
type { FactoryGirl.create(:hunt_type) }
end
end
My shrine initializer :
require "shrine"
require "shrine/storage/fog"
require "fog"
if Rails.env == 'test'
require "shrine/storage/memory"
Shrine.storages = {
cache: Shrine::Storage::Memory.new,
store: Shrine::Storage::Memory.new,
}
else
ovh_service = Fog::Storage.new(
provider: ENV['PROVIDER'],
openstack_username: ENV['OPEN_STAK_USERNAME'],
openstack_api_key: ENV['OPEN_STACK_API_KEY'],
openstack_auth_url: ENV['OPEN_STACK_AUTH_URL'],
openstack_region: ENV['OPEN_STACK_REGION'],
openstack_temp_url_key: SecureRandom.urlsafe_base64(nil, false),
)
Shrine.storages[:store] = Shrine::Storage::Fog.new(
connection: ovh_service,
directory: ENV['OPEN_STACK_FOLDER_NAME'],
expires: 24,
type: 'public'
)
Shrine.storages[:cache] = Shrine::Storage::Fog.new(
connection: ovh_service,
directory: ENV['OPEN_STACK_FOLDER_NAME'],
type: 'public'
)
end
My uploader :
require "image_processing/mini_magick"
class ImageUploader < Shrine
# plugins and uploading logic
include ImageProcessing::MiniMagick
plugin :activerecord
plugin :cached_attachment_data # for forms
plugin :upload_endpoint
plugin :processing
plugin :versions # enable Shrine to handle a hash of files
plugin :delete_raw # delete processed files after uploading
plugin :validation_helpers
plugin :determine_mime_type
Attacher.validate do
validate_extension_inclusion %w[jpg jpeg png gif]
validate_mime_type_inclusion %w[image/jpeg image/png image/gif]
end
process(:store) do |io, context|
original = io.download
size_800 = resize_to_limit!(original, 800, 800) { |cmd| cmd.auto_orient } # orient rotated images
size_500 = resize_to_limit(size_800, 500, 500)
size_300 = resize_to_limit(size_500, 300, 300)
size_150 = resize_to_limit(size_300, 150, 150)
size_60 = resize_to_limit(size_150, 60, 60)
{ original: io, large: size_800, medium: size_500, card: size_300, little: size_150, small: size_60 }
end
end
And my route :
mount ImageUploader.upload_endpoint(:cache) => "/images/upload"
I really don't know from where it can be from... Any idea ?
Thanks in advance !
The delete_raw plugin is deleting your test file. The reason why this happens on version 2.7.0 and not before is that the delete_raw plugin was recently fixed to also work on File objects in addition to Tempfile objects.
There are several solutions. One solution is to configure delete_raw plugin to only delete raw files that are uploaded to permanent storage:
plugin :delete_raw, storages: [:store]
Another solution is to provide a StringIO object in your factory definition:
require "stringio"
FactoryGirl.define do
factory :hunt do
# ...
picture { StringIO.new(File.binread("spec/fixtures/files/picture.jpg")) }
# ...
end
end
I don't like how magical the delete_raw and similar plugins are, it would be better specifying deletion was opt-in instead of opt-out, such as passing a :delete_raw option on uploading. I will rethink this in the future, but for now these two options are the idiomatic solutions.
Hello @janko!
I use shrine 3.2.1 and have this problem, but i not use delete_raw plugin.
I have derivatives plugin. What argument pass to plugin :derivatives, that disable delete source file?
Hi @Yegorov , please ask this question on the Discourse forum for questions! https://discourse.shrinerb.com/
I am not sure exactly what you are doing, but you may be running into what's documented here. But please don't discuss this anymore on this Github issue, please use the discourse forum -- or if you are confident it's a bug, please file a separate ticket with a complete description of the problem and a reproducible test case. Thanks for using shrine and providing feedback!
Most helpful comment
The
delete_rawplugin is deleting your test file. The reason why this happens on version 2.7.0 and not before is that thedelete_rawplugin was recently fixed to also work onFileobjects in addition toTempfileobjects.There are several solutions. One solution is to configure
delete_rawplugin to only delete raw files that are uploaded to permanent storage:Another solution is to provide a
StringIOobject in your factory definition:I don't like how magical the
delete_rawand similar plugins are, it would be better specifying deletion was opt-in instead of opt-out, such as passing a:delete_rawoption on uploading. I will rethink this in the future, but for now these two options are the idiomatic solutions.