Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to upload while resizing the original image itself in Shrine

I use Shrine in a Ruby on Rails application to create the process of resizing and uploading images to storage.

My current code is:


image_uploader.rb

require "image_processing/mini_magick"

class ImageUploader < Shrine
  plugin :derivatives

  Attacher.derivatives_processor do |original|
    magick = ImageProcessing::MiniMagick.source(original)
    {
      resized: magick.resize_to_limit!(120, 120)
    }
  end

end

user.rb

class User < ApplicationRecord
  include ImageUploader::Attachment(:image)
  before_save :image_resize

  def image_resize
    self.image_derivatives!
  end
end

I implemented it while reading the official documentation, but this is not desirable in two ways.

  1. Requires trigger in model code. Can it be completed with only image_uploader.rb?
  2. Access to images generated with this code requires a "resized" prefix(e.g. @user.image(:resized).url), and the original image will also remain in storage. I want to process the original image itself.

Is there a way to upload while solving these two issues?

like image 842
sink66 Avatar asked Sep 14 '25 05:09

sink66


1 Answers

  1. You can add the following patch, which will trigger derivatives creation as part of promoting cached file to permanent storage:

    # put this in your initializer
    class Shrine::Attacher
      def promote(*)
        create_derivatives
        super
      end
    end
    
  2. You can just override the model method that retrieves the attached file to return the resized version. You can use the included plugin to do this for all models using this uploader:

    class ImageUploader < Shrine
      # ...
      plugin :included do |name|
        define_method(name) { super(:resized) }
      end
    end
    

As for the second question: It will still keep the original file in the storage, but just return the resized version instead by default. It's generally better to do this in a view decorator instead.

You always want to keep the original file in the storage, because you never know when you'll need to reprocess it. It can happen that you find your current resizing logic not to be ideal for certain filetypes and sizes, in which case you'll need to regenerate the resized version for previous attachments. And you wouldn't be able to do that if you didn't have the original file anymore.

like image 172
janko-m Avatar answered Sep 15 '25 17:09

janko-m