If remove_invalid plugin is written before derivative plugin, derivative is deleted if validation fails

I have been using shrine and it is very helpful. Thanks to all contributors.

I have a question this time.
I found strange behavior like the topic title. Is this a bug? or is it a specification? code and reproduction procedure is as follows.

shrine 3.1.0
rails 6.0.0


require "image_processing/mini_magick"

class ImageUploader < Shrine
  # OK
  # plugin :derivatives
  # plugin :remove_invalid
  # plugin :validation

  # NG
  plugin :remove_invalid
  plugin :derivatives
  plugin :validation

  Attacher.derivatives do |original|
    magick = ImageProcessing::MiniMagick.source(original)

      small:  magick.resize_to_limit!(100, 100)

  Attacher.validate do
    # DEBUG: always fail
    # errors << "fail"


require "shrine"
require "shrine/storage/file_system"

Shrine.storages = { 
  cache: Shrine::Storage::FileSystem.new("public", prefix: "uploads/cache"), # temporary 
  store: Shrine::Storage::FileSystem.new("public", prefix: "uploads"),       # permanent 

class Shrine::Attacher
  def promote(*)

Shrine.plugin :activerecord


<p id="notice"><%= notice %></p>

  <%= @user.name %>
  <%= image_tag @user.image_url %>
  <%= image_tag @user.image(:small).url %>

<%= link_to 'Edit', edit_user_path(@user) %> |
<%= link_to 'Back', users_path %>

Reproduction procedure

  1. Register model.

  2. Check the derivatives display.(image(:small).url)

  3. Check that the original image and derivative are in storage.

  4. Uncomment # errors << "fail" in image_uploader.rb

  5. Update model.

  6. Validation error occurs.

  7. Derivatives are deleted.


all code is here

Hi, thanks for reporting, and I’m glad you’re finding Shrine useful :smiley:

Yes, this is definitely a bug, and it’s coming from the plugin load order. A simple workaround would be to load the derivatives plugin before the remove_invalid plugin:

# ...
plugin :derivatives
plugin :remove_invalid
# ...

I will try to come up with a fix that will make the opposite order work as well.

1 Like

Actually, that wouldn’t work as well, because remove_invalid plugin wouldn’t assign back the original derivatives on validation errors, as I forgot to handle that case. I will include the fix for this as well.

1 Like

Thank you for your time.
I look forward to the fix.:slightly_smiling_face:

I’ve just pushed a fix for the remove_invalid + derivatives incompatibility to master, would you mind giving it a spin?

The next version (which will include this fix) should be released by the end of this week.

I tried the same procedure using the master branch (@15bd6322).
Derivatives were not deleted. Looks like it ’s okay.
Thank you for your nice work!

1 Like