ruby-on-railsrails-activestoragewicked-pdf

Use ActiveStorage Image in wicked_pdf


I can't get ActiveStorage images to work in production. I want to use a resized image (variant) within the body of the PDF I'm generating.

= image_tag(@post.image.variant(resize_to_limit: [150, 100]))

It worked in development but in production generating the PDF hangs indefinitely unless I take that line out.

I've tried things like @post.image.variant(resize_to_limit: [150, 100]).processed.url and setting Rails.application.default_url_options = { host: "example.com" }

Ironically when I restart Passenger it sends the PDF to the browser and it actually looks fine. The image is included.

This is similar:

= wicked_pdf_image_tag(@post.image.variant(resize_to_limit: [150, 100]).processed.url)

Rails 7.0.3, Ruby 3.1.2, wicked_pdf 2.6.3


Solution

  • Thanks to @Unixmonkey I added passenger_min_instances 3; to my server block in Nginx config and it worked initially but would hang Passenger under load. Since I didn't have the RAM to throw at increasing that number I came up with a different solution based on reading images from file.

    = image_tag(active_storage_to_base64_image(@post.image.variant(resize_to_limit: [150, 100])))
    

    Then I created a helper in application_helper.rb

    def active_storage_to_base64_image(image)
      require "base64"
      file = File.open(ActiveStorage::Blob.service.path_for(image.processed.key))
      base64 = Base64.encode64(file.read).gsub(/\s+/, '')
      file.close
      "data:image/png;base64,#{Rack::Utils.escape(base64)}"
    end
    

    I've hard coded it for PNG files as that's all I needed. Only works for Disk storage. Would welcome improvements