Moving uploads from cache to store

214 views
Skip to first unread message

luvm...@gmail.com

unread,
Aug 12, 2016, 6:42:53 PM8/12/16
to Shrine
Hi. I'm trying to implement shrine into my project and having some problems that I'm hoping you can help me with.

I followed the example for the image uploading from the docs, but
I think I missed something.  Whenever I try to upload the attachments through the Asset form, the file is uploaded to uploads/cache and the information is saved as such. It was never transferred over to uploads/store. When I upload images using associated uploader (shown below), with versioning, the images seem to processed and stored correctly. For documents, I just want to save the files as is without any processing and it will just saved to cache. Can you tell me what I'm missing? Do I need to add direct_upload plugin?

# app/models/image_uploader.rb
class ImageUploader < Shrine
include ImageProcessing::MiniMagick

plugin :activerecord
plugin :determine_mime_type
plugin :logging, logger: Rails.logger
plugin :remove_attachment
plugin :store_dimensions
plugin :validation_helpers
plugin :versions, names: [:original, :thumb]

Attacher.validate do
validate_max_size 2.megabytes, message: 'is too large (max is 2 MB)'
validate_mime_type_inclusion ['image/jpg', 'image/jpeg', 'image/png', 'image/gif']
end

def process(io, context)
case context[:phase]
when :store
thumb = resize_to_limit!(io.download, 200, 200)
{ original: io, thumb: thumb }
end
end
end


# app/models/document_uploader.rb
class DocumentUploader < Shrine
plugin :validation_helpers
plugin :determine_mime_type
plugin :parallelize
plugin :logging, logger: Rails.logger
plugin :remove_attachment
plugin :delete_raw

Attacher.validate do
validate_max_size 10*1024*1024, message: "is too large (max is 10 MB)"
validate_extension_inclusion [/jpe?g/, "png", "gif", "txt", "pdf", "doc", "docx", "xls", "xlsx"]
validate_mime_type_inclusion ["image/jpeg", "image/png", "image/gif", "application/pdf", "text/plain",
"application/msword", "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
"application/vnd.ms-excel", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"]
#end
end

def process(io, context)
case context[:phase]
when :store
{ original: io }
end
end

end

Janko Marohnić

unread,
Aug 12, 2016, 10:55:46 PM8/12/16
to luvm...@gmail.com, Shrine
If I got it correctly, ImageUploader attachments are saved to permanent storage, but DocumentUploader attachments aren't? In that case it's probably due to the fact that you didn't load the activerecord plugin in DocumentUploader.

As the "Quick Start" section of the README suggests, it's much better to load plugins that you want in all uploaders globally (and then the rest you load for each uploader individually):

Shrine.plugin :activerecord
Shrine.plugin :determine_mime_type
Shrine.plugin :logging, logger: Rails.logger
Shrine.plugin :validation_helpers
# ...

Unfortunately, I still see people trip up on this (not loading the activercord plugin and then the attachment simply not being uploaded to permanent storage), I will try to improve the README somehow.

Kind regards,
Janko Marohnić


--
You received this message because you are subscribed to the Google Groups "Shrine" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ruby-shrine...@googlegroups.com.
To post to this group, send email to ruby-...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/ruby-shrine/b3bb89a4-2008-4cda-b566-8f2825baae97%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Janko Marohnić

unread,
Aug 12, 2016, 11:01:34 PM8/12/16
to luvm...@gmail.com, Shrine
Btw, I noticed you are using older version of Shrine or documentation, if you update to newest version you can remove `:names` option from the versions plugin, and the processing is now much nicer to write with the processing plugin.

Also, if you don't intend to do any processing in DocumentUploader, you don't have to define the #process method ;)

Regards,
Janko

luvm...@gmail.com

unread,
Aug 17, 2016, 3:28:39 PM8/17/16
to Shrine
Thanks for your help. I added activerecord plugin to DocumentUploader, but it still won't move the files from cache to store. However, removing the process method worked. Following the examples, I thought the process method was needed to move the files from cache to store, even when it doesn't really do anything.

I checked and I was using v.2.0.1 of the gem. I updated it and updated all my codes following the readme again. Didn't know the documentation was changed. It is indeed much cleaner now.

I tried to subclass an uploader as you suggested but it doesn't seem to work correctly.
class AvatarUploader < ImageUploader

Do you only supposed to inherit directly from the initializer, and not from another uploader? I noticed that the initializer shrine.rb uses Shrine.plugin while other uploaders only using plugin. Does it make a difference?


Janko Marohnić

unread,
Aug 18, 2016, 4:30:32 AM8/18/16
to luvm...@gmail.com, Shrine
Thanks for your help. I added activerecord plugin to DocumentUploader, but it still won't move the files from cache to store.

Can you try reproducing this bug in a self-contained example? You can try setting it up with the help of the ActiveRecord template. Do you notice anything that's different from the shrine-rails-example application?

I tried to subclass an uploader as you suggested but it doesn't seem to work correctly.
class AvatarUploader < ImageUploader
You can do this inheritance if you want to share some logic between multiple uploaders, just like regular inheritance. What doesn't work correctly?
Do you only supposed to inherit directly from the initializer, and not from another uploader?
You can inherit directly from Shrine, or from another uploader, depending on how you want to organize your logic. For example, you can have ImageUploader share some common logic between an AvatarUploader and e.g. a PhotoUploader (just like I mentioned above).
I noticed that the initializer shrine.rb uses Shrine.plugin while other uploaders only using plugin. Does it make a difference?
When you call `Shrine.plugin`, this plugin will be applied to all uploaders. When you call `plugin` inside an ImageUploader (which is equivalent to calling `ImageUploader.plugin`), it will be applied only for that uploader and its subclasses. So imagine that `Shrine` is an abstract uploader, and when you call `Shrine.plugin`, all uploaders that inherit from `Shrine` (which are all uploaders) will have this plugins applied. In other words, the plugin system respects inheritance. To answer your question, it doesn't make a difference whether it's global or local.

Kind regards,
Janko

Reply all
Reply to author
Forward
0 new messages