When creating an AR object with image_data taken from Uppy the activerecord plugin does not run callbacks. It's impossible to run processing or backgrounding plugins.
The reason behind it is probably the attacher which changed? method always returns false. Even with assign being called manually.
After saving a record with attachment data from Uppy the activerecord, processing and backgrounding plugins would work as expected.
The activerecord callbacks are in fact run, but they quit at the beginning because of attacher.changed? being false which prevents them from doing any action. The processing plugin does not work - process block is never called. The backgrounding plugin does not work - promote block is never called.
_config/initializers/shrine.rb_
# frozen_string_literal: true
require 'shrine'
require 'shrine/storage/s3'
s3_options =
{}.tap do |hash|
hash[:access_key_id] = ENV['AWS_S3_ACCESS_KEY_ID']
hash[:secret_access_key] = ENV['AWS_S3_SECRET_ACCESS_KEY']
hash[:bucket] = ENV['AWS_S3_BUCKET']
hash[:region] = ENV['AWS_S3_REGION']
end
Shrine.storages = {
cache: Shrine::Storage::S3.new(prefix: 'cache', **s3_options),
store: Shrine::Storage::S3.new(prefix: 'uploads', **s3_options)
}
Shrine.plugin :instrumentation
Shrine.plugin :determine_mime_type
Shrine.plugin :presign_endpoint,
presign_options: lambda { |request|
filename = request.params['filename']
type = request.params['type']
{
content_disposition: "inline; filename=\"#{filename}\"",
content_type: type,
content_length_range: 0..(10 * 1024 * 1024), # limit upload size to 10 MB
success_action_status: '201'
}
}
_app/uploaders/image_uploader.rb_
# frozen_string_literal: true
require 'image_processing/mini_magick'
class ImageUploader < Shrine
plugin :activerecord
plugin :processing
plugin :versions
plugin :store_dimensions
plugin :delete_raw
process(:cache) do |io, context|
binding.pry
end
process(:store) do |io, context|
binding.pry
end
def process(io, context)
binding.pry
end
end
_app/models/image.rb_
class Image < ApplicationRecord
include ImageUploader[:image]
belongs_to :owner, polymorphic: true
end
and the operation itself:
# data contains image_data with uppy json
profile_image = owner.profile_image || ProfileImage.new(owner: owner)
data.delete(:id) if profile_image.persisted?
profile_image.tap do |pi|
pi.assign_attributes(data)
pi.save!
end
Ruby version: 2.6.3
Shrine version: 2.19.3
Hi Mateusz, sorry for not replying to your earlier email.
Are you assigning to the image_data column attribute directly? You should be assigning the image attribute. Shrine doesn't detect changes to the image_data attribute, it's only intended as a backdoor when you want to bypass Shrine.
Hi Janko
Thank you so so much!
I spent more time on that that I’d like to admit and I knew it must’ve been something silly :)
As you’ve already seen, I started an issue on GitHub.
I’ll post a comment shortly that it solves the issue and you can close it.
Maybe it’s a good idea to put that little trick in the documentation somewhere because it slipped my attention.
Thank you very much again,
All the best,
Mateusz
On 20 Aug 2019, 12:53 +0200, Janko Marohnić notifications@github.com, wrote:
Hi Mateusz, sorry for not replying to your earlier email.
Are you assigning to the image_data column attribute directly? You should be assigning the image attribute. Shrine doesn't detect changes to the image_data attribute, it's only intended as a backdoor when you want to bypass Shrine.
—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub, or mute the thread.
Most helpful comment
Hi Mateusz, sorry for not replying to your earlier email.
Are you assigning to the
image_datacolumn attribute directly? You should be assigning theimageattribute. Shrine doesn't detect changes to theimage_dataattribute, it's only intended as a backdoor when you want to bypass Shrine.