Search code examples
ruby-on-railselectronrails-activestorage

Is it possible to display images from rails active storage inside another application using a URL?


I'm trying to access the User avatar object from a rails API/backend using active storage and display it inside an electron desktop application using a <img> tag. I've been trying various combinations of URL formats in the src attribute of the image tag but always run into a rails routing error.

I've tried using the key, and the attached_sgid fields from rails with the URL formats below but neither approaches work.

http://localhost:3000/rails/active_storage/blobs/--active_storage_blobs.key--
http://localhost:3000/rails/active_storage/blobs/--attached_sgid--


Gives this error:

No route matches [GET] "/rails/active_storage/blobs/BAh7CEkiCGdpZAY6BkVUSSIqZ2lkOi8vanVtcHN0YXJ0LWFwcC9Vc2VyLzE_ZXhwaXJlc19pbgY7AFRJIgxwdXJwb3NlBjsAVEkiD2F0dGFjaGFibGUGOwBUSSIPZXhwaXJlc19hdAY7AFQw--2465471c08be19196738d37c7f02be10c4a88bba"

Is it even possible to display an image from active storage in this way?


Solution

  • I believe you should return the url ready to be used from your backend API instead of building the URL on your electron app.

    You can find the correct url from your model using:

    url_for(user.avatar)
    

    There are some options to return it. If you don't mind making your model a bit dirty, you can create a method called avatar_url and then return this value with your json.

    # new method on model
    def avatar_url
      Rails.application.routes.url_helpers.url_for(avatar)
    end
    
    # on controller controller
    def show
      user = User.find(params[:id])
      render json: user, methods: [:avatar_url]
    end
    

    A cleaner option is to create a jbuilder on to build the json for you, and add the url there:

    # create new jbuilder file app/view/users/show.json.jbuilder
    json.id @user.id
    json.avatar_url url_for(@user.avatar) if post.avatar.attached?
    
    # on controller controller
    def show
      @user = User.find(params[:id])
      respond_to do |format|
        format.json
      end
    end