Search code examples
ruby-on-railsrubyruby-on-rails-4minimagick

Minimagick: undefined method `destroy!' for true:TrueClass auto_orient


I have an image uploaded that works as expected except when I add an additional process (auto_orient) to the ImageUploader. Codes is as follows:

class ImageUploader < CarrierWave::Uploader::Base
  include CarrierWave::MiniMagick

  retina!

  if Rails.env.development?
    def store_dir
      "#{Rails.root}/public/uploads/account_#{model.account_id}/product_#{model.product_id}/image_#{model.id}"
    end
  elsif Rails.env.staging? || Rails.env.production?
    def store_dir
      "uploads/account_#{model.account_id}/product_#{model.product_id}/image_#{model.id}"
    end
  end

  def default_url
    "/assets/no_image_500px.png"
  end


  process :auto_orient
  process :resize_and_pad => [500, 500]

  version :thumb_100 do
    process :resize_and_pad => [100, 100]
  end

  version :shopping_cart do
    process :resize_to_fill => [200, 200]
    process :retina_quality => 100
  end

  version :store_page do
    process :resize_to_fill => [336, 336]
    process :retina_quality => 100
  end

  version :product_page do
    process :resize_to_fill => [426, 426]
    process :retina_quality => 100
  end

  def extension_white_list
    %w(jpg jpeg png tiff)
  end

  def auto_orient
    manipulate! do |img|
      img = img.auto_orient
    end
  end

end

Auto_orient serves the purpose for a user to upload an image from their mobile phone, the image is auto oriented properly. This current code works for mobile uploaded images, but when I try to upload images from the web app on a desktop, I receive: "undefined method `destroy!' for true:TrueClass".

I've looked at the documentationfor minimagick and thought changing auto_orient to auto_orient! but then I'm told minimagick has no method named auto_orient! Why is destroy being called with this method?


Solution

  • It looks like manipulate! calls a destroy method on the return of auto_orient (which ends up being a boolean (true)). Hence the error for unable to call delete on a boolean. To fix this, I added the ruby "tap" method to pass in the image to the block and then return the image immediately afterwards:

      def auto_orient
        manipulate! do |img|
          img.tap(&:auto_orient)
        end
      end