1
votes

Rails 6 app with ActiveStorage has a application helper that returns the profile image of a user.

 module ApplicationHelper
        def profile_picture_with_class user, css_class, shape, width = 100
            if (shape == :square)
                placeholder_pic = "blank_profile_square.jpg"
            else
                placeholder_pic = "blank_profile_round.png"
            end
            image_path = user.profile_image.present? ? user.profile_image : placeholder_pic
            image_tag(image_path, width: width, class: css_class)
        end 
    end

When this applicationHelper is called from within the app it works fine. If however a redis job uses this applicationHelper the returned image_tag is going to instead of my apps actual host (localhost:3000 in dev) and this creates a very broken link.

I'm guessing since this is firing off inside a redis job it doesnt know what the host is so its prepending something else. How can I get it to understand to use the correct host and active storage type (disk vs blob)

Thanks.

Comparison of the two created links:

Example:

Redis returns this:

http://example.org/rails/active_storage/blobs/<big_long_chunk>/new-chimney-crown.jpg

When run within a view it returns this:

http://localhost:3000/rails/active_storage/disk/<big_long_chunk>/new-chimney-crown.jpg?content_type=image%2Fjpeg&disposition=inline%3B+filename%3D%22new-chimney-crown.jpg%22%3B+filename%2A%3DUTF-8%27%27new-chimney-crown.jpg

Edit: I'm pretty sure it has something to do with this: https://evilmartians.com/chronicles/new-feature-in-rails-5-render-views-outside-of-actions

This is the redis job, I believe that when image_path is called from within ChatMessagesController.render it is not understanding the current host.

  def perform(chat_message)
    ActionCable.server.broadcast "stream:#{chat_message.stream.id}", {
        chat_message: ChatMessagesController.render(chat_message)       
    }
1

1 Answers

0
votes
  def perform(chat_message)
    # ChatMessagesController.renderer.defaults[:http_host] = ENV['RAILS_APPLICATION_URL'].presence || 'http://localhost:3000' 

    renderer = ChatMessagesController.renderer.new(
      http_host: ENV['RAILS_APPLICATION_URL'].presence || 'http://localhost:3000' ,
      https:      Rails.env.production?
    )

    ActionCable.server.broadcast "stream:#{chat_message.stream.id}", {
        chat_message: renderer.render(chat_message)         
    }

  end

So the defaults for whatever reason are reset to example.com while its running. If I create a renderer and specifically set its host (and ssl) it seems to work fine. SSL must be set correctly as well or it won't work.