34

I want to get list of records with attached images as a links or files by api.

I have a simple model:

class Category < ApplicationRecord
  has_one_attached :image
  validates :name, presence: true, uniqueness: true
end

And next action:

  def index
    @categories = Category.all.with_attached_image

    render json: @categories.to_json(include: { image_attachment: { include: :blob } })
  end

That's the only way I can get image object.

And I see next results:

{"id":4,"name":"Cat1","description":""},
{"id":1,"name":"Cat2","description":"","image_attachment":
  {"id":8,"name":"image","record_type":"Category","record_id":1,"blob_id":8,"created_at":"2018-06-09T13:45:40.512Z","blob":
  {"id":8,"key":"3upLhH4vGxZEhhf3TaAjDiCW","filename":"Screen Shot 2018-06-09 at 20.43.24.png","content_type":"image/png","metadata":
  {"identified":true,"width":424,"height":361,"analyzed":true},"byte_size":337347,"checksum":"Y58zbYUVOlZRadx81wxOJA==","created_at":"2018-06-09T13:45:40.482Z"}}},
...

I can see filename here. But files lives in different folders and it doesn't seems for me like a convenient way to get and link to the file.

I couldn't find any information about this.

Updated

Accordin to iGian solution my code become:

  def index
    @categories = Category.all.with_attached_image

    render json: @categories.map { |category|
      category.as_json.merge({ image: url_for(category.image) })
    }
  end
zishe
  • 10,665
  • 12
  • 64
  • 103

7 Answers7

49

For my User which has_one_attached :avatar I can get the url in my views with <%= image_tag url_for(user.avatar) %>. So, in controller I would use just url_for(user.avatar)

For Category which has_one_attached :image:

url_for(category.image)
iGian
  • 11,023
  • 3
  • 21
  • 36
16

Also try @object.image.service_url. This will give you the url where the image is saved. I.E. url to amazon s3 storage.

AnthonyM.
  • 339
  • 2
  • 5
4

Please follow this for fetching images( in case if you are using has_many_attached)

Model.images.map{|img| ({ image: url_for(img) })}
Luca Kiebel
  • 9,790
  • 7
  • 29
  • 44
  • I'm afraid I can't convert from single to multiple attachments using only the the line in your answer. I get either just the 'images' array in the response, or an error, meaning I'm doing something wrong. Could you possibly put this answer into the context of the original poster's 'index' method block? – bcsantos May 17 '19 at 11:04
  • 1
    I got this to work, would it be the correct way, syntactically? `render json: @works.map { |work| work.as_json.merge({ images: work.images.map{|img| ({ image: url_for(img) })} }) } ` – bcsantos May 17 '19 at 11:20
4

This works for me with multiple images

class PostSerializer < ActiveModel::Serializer
  include Rails.application.routes.url_helpers

  attributes :id, :content , :images

  def images
    images = object.images.map do |image|
      rails_blob_path(image , only_path: true) if object.images.attached?
    end
  end
end
2

I got it to work with rails_blob_url(@object.image). Notice I am calling _url not _path with the helper.

AnthonyM.
  • 339
  • 2
  • 5
1

If you want get this url in front end, try this :

<%= url_for(category.image) %>

and for displaying image :

<%= image_tag url_for(category.image) %>
Meloman
  • 3,558
  • 3
  • 41
  • 51
1

Here is how I use active storage with AWS S3 bucket and attach image urls with domain to JSON response:

activerecord


class Imageable < ApplicationRecord
  has_many_attached :images

  def image_urls
    images.map(&:service_url)
  end

  def attributes
    super.merge({
                  image_urls: image_urls
                })
  end
end

application_controller.rb

class ApplicationController < ActionController::Base
  before_action :set_active_storage_current_host
  
  def set_active_storage_current_host
    ActiveStorage::Current.host = request.base_url
  end
end

imageables_controller.rb

class ImageablesController < ApplicationController
  include ImageablesHelper
  def update
    imageable = find_or_create
    imageable.update imageables_params
    imageable.images.purge
    imageable.images.attach imageable_params[:images]
    imageable.save!
    render json: imageable
  end
end

imageables_helper.rb

module ImageablesHelper
  def imageables_params
    params.require(:imageable).permit(:other_attributes, images: [])
  end
end
glinda93
  • 7,659
  • 5
  • 40
  • 78