Skip to content

Instantly share code, notes, and snippets.

@aried3r aried3r/shrine_copy.rb
Last active Mar 14, 2018

Embed
What would you like to do?
Reproduces a possible bug within the shrine copy plugin
require "active_record"
require "shrine"
require "shrine/storage/file_system"
require "tmpdir"
require "open-uri"
Shrine.plugin :activerecord
Shrine.plugin :logging
# Comment in this line to make the last example work
# Shrine.plugin :keep_files, replaced: true
Shrine.storages = {
cache: Shrine::Storage::FileSystem.new(Dir.tmpdir, prefix: "cache"),
store: Shrine::Storage::FileSystem.new(Dir.tmpdir, prefix: "store"),
}
class MyUploader < Shrine
plugin :copy
plugin :pretty_location
end
ActiveRecord::Base.establish_connection(adapter: "sqlite3", database: ":memory:")
ActiveRecord::Base.connection.create_table(:posts) { |t| t.text :image_data }
class Post < ActiveRecord::Base
include MyUploader::Attachment.new(:image)
end
post = Post.create(image: open("http://via.placeholder.com/350x150"))
# Your code for reproducing
# Prints something like 'post/1/image/71c64e1140543ee0147374ede1492e9b'
puts "Original ID: #{post.image.id}"
# After calling `.dup`, `copy` is not yet saved, so the ID will be missing
# Prints something like 'post/image/71c64e1140543ee0147374ede1492e9b'
copy = post.dup
puts "Copy ID: #{copy.image.id}, using '.dup', before '.save'"
# Before saving `generate_location` is not called again, ID still missing
# Prints the same as the previous statement:
# 'post/image/71c64e1140543ee0147374ede1492e9b'
copy.save
puts "Copy ID: #{copy.image.id}, after '.save'"
# Running promote manually, we get the ID again
# Prints something like 'post/2/image/4a66045cf7b0e4c66cc8fdf5ff75a5c1'
copy.image_attacher.promote(action: :migrate)
puts "Copy ID: #{copy.image.id}, after manually promoting"
# Using the workaround in https://github.com/janko-m/shrine/issues/237#issuecomment-358373824
puts "Using the workaround:"
puts "Original exists: #{post.image.exists?}"
Post.transaction do # make this operation appear atomic
copy = Post.create(post.attributes.except("id"))
copy.image_attacher.copy(post.image_attacher)
# ID will be something like "post/3/image/38007749b97452fdf38b9404eede391f"
puts "Second copy ID: #{copy.image.id}, using the workaround"
copy.save
end
puts "Original exists: #{post.image.exists?}"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.