Search code examples
ruby-on-railsimage-processingminimagick

Active Storage File Not Found error when trying to use ImageProcessing


I keep getting

ActiveStorage::FileNotFoundError (ActiveStorage::FileNotFoundError):
app/models/service.rb:24:in `process_images'

When trying to load an image into ImageProcessing::MiniMagick using ImageProcessing::MiniMagick.source(self.image.download)

I have also tried

ImageProcessing::MiniMagick.source(self.image) ImageProcessing::MiniMagick.source(self.image.attachment) ImageProcessing::MiniMagick.source(self.image.attachment.download) ImageProcessing::MiniMagick.source(self.image.blob)

ImageProcessing doesn't like those as its looking for a url so I tried using a url as well like this url = Rails.application.routes.url_helpers.rails_blob_path(self.image, only_path: true) and passing that in instead of self.image When I do that I get the error

failed with error:
convert: unable to open image `rails/active_storage/blobs/foo...`

Can someone please steer me in the right direction.

here is the relevant part of my Model as it looks now.

class Service < ApplicationRecord
  has_one_attached :image, dependent: :destroy
  has_one_attached :featured_image, dependent: :destroy

  after_create :process_images
  after_save :process_images

  private  
  def process_images 
    url = Rails.application.routes.url_helpers.rails_blob_path(self.image, only_path: true)
    pipeline1 = ImageProcessing::MiniMagick.source(url)
    #can't continue until I load an image
  end
end

I have also called the method from the controller. I made the model method not private and called it and it solved the nil attachment issue. The following but then I get this error. ArgumentError (string contains null byte): flagged at this line. pipeline1.resize_to_limit(400,400).convert("jpg").call

All I'm trying to do is resize images when the instance is created or updated and then save the processed image as the main attachment.


Solution

  • According to the documentation "The source object needs to responds to .path, or be a String, a Pathname, or a Vips::Image/MiniMagick::Tool object", none of the arguments you provided met the requirements.

    My approach was to get the full path of your ActiveStorage file, for this we can use ActiveStorage::Blob.service.send(:path_for, <attachment>), and then use this as an argument in the ImageProcessing::MiniMagick.source method.

    That's why the following works:

    ImageProcessing::MiniMagick.source(ActiveStorage::Blob.service.send(:path_for, self.image.key))