This one is a bit mystifying. I removed my namespaces from the job to take it out of the equation, but still see the same error. Is the structure of shrine compatible with namespaced usage? What am I missing here?
NoMethodError:
undefined method `promote' for Shrine::Attacher:Class
# ./app/jobs/shrine_promote_job.rb:6:in `perform'
# /Users/kross/.rvm/gems/ruby-2.4.1@af/gems/sidekiq-5.0.5/lib/sidekiq/testing.rb:301:in `execute_job'
module Af
module Uploader
class PdfUploader < ::Shrine
plugin :determine_mime_type
plugin :validation_helpers
Attacher.validate do
validate_extension_inclusion %w(pdf)
validate_max_size 15.megabytes, message: 'is too large (max is 15 MB)'
validate_mime_type_inclusion ['application/pdf']
end
end
end
end
module Af
module Uploader
class BackgroundPdfUploader < PdfUploader
plugin :backgrounding
Attacher.promote { |data| ShrinePromoteJob.perform_async(data) }
Attacher.delete { |data| ShrineDeleteJob.perform_async(data) }
end
end
end
class ShrinePromoteJob
include ::Sidekiq::Worker
def perform(data)
Shrine::Attacher.promote(data)
end
end
module Af
module Commerce
class Agreement < ActiveRecord::Base
if Af.dev?
# in dev, do everything in the foreground to ease seeding
include Af::Uploader::PdfUploader::Attachment.new(:document)
else
# in every other environment, background the work
include Af::Uploader::BackgroundPdfUploader::Attachment.new(:document)
end
end
end
end
Note, the same results occur with explicit root Shrine namespace usage from the job:
class ShrinePromoteJob
include ::Sidekiq::Worker
def perform(data)
::Shrine::Attacher.promote(data)
end
end
I also tried collapsing the BackgroudPdfUploader so it had no other hierarchy:
module Af
module Uploader
class BackgroundPdfUploader < ::Shrine
plugin :determine_mime_type
plugin :validation_helpers
Attacher.validate do
validate_extension_inclusion %w(pdf)
validate_max_size 15.megabytes, message: 'is too large (max is 15 MB)'
validate_mime_type_inclusion ['application/pdf']
end
plugin :backgrounding
Attacher.promote { |data| ShrinePromoteJob.perform_async(data) }
Attacher.delete { |data| ShrineDeleteJob.perform_async(data) }
end
end
end
Same error.
If I move the backgrounding setup to the initializer, it all works, so it appears it has be turned on or off for the entire system.
Figured it out.
The plugin provides Attacher.promote and Attacher.delete methods, which allow you to hook up to promoting and deleting and spawn background jobs, by passing a block.
Shrine.plugin :backgrounding
Shrine::Attacher.promote { |data| PromoteJob.perform_async(data) }
Shrine::Attacher.delete { |data| DeleteJob.perform_async(data) }
If you don't want to apply backgrounding for all uploaders, you can declare the hooks only for specific uploaders.class MyUploader < Shrine
Attacher.promote { |data| PromoteJob.perform_async(data) }
Attacher.delete { |data| DeleteJob.perform_async(data) }
end
It might be worth noting in this section, that the Shrine.plugin :backgrounding must be done in the initializer, even though you select the specific uploaders to do the:
Attacher.promote { |data| PromoteJob.perform_async(data) }
Attacher.delete { |data| DeleteJob.perform_async(data) }
The current doc is technically correct, but this is a bit of a gotcha/hard to spot.
Glad that you figured it out by yourself. Ok, I'll see how I can make the backgrounding documentation a bit clearer.
Most helpful comment
Figured it out.
It might be worth noting in this section, that the
Shrine.plugin :backgroundingmust be done in the initializer, even though you select the specific uploaders to do the:The current doc is technically correct, but this is a bit of a gotcha/hard to spot.