Reputation: 10825
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
Upvotes: 37
Views: 64364
Reputation: 489
We can just use
<%= image_tag url_for(user.avatar) %>
to display any image from Turbo Stream.
For example, showing real-time post notifications with Turbo Stream, we can use following code for post partial
<!-- app/views/notifications/_post.html.erb -->
<div class="flex items-start space-x-4 bg-white p-4 rounded-lg shadow-md">
<% if notification.item.user.avatar.attached? %>
<%= image_tag url_for(notification.item.user.avatar), class: 'w-10 h-10 rounded-full' %>
<% end %>
<div class="flex-grow">
<p class="text-gray-700">
<span class="font-semibold text-gray-900"><%= notification.item.user.username %></span>
added a new post:
</p>
<p class="mt-1 text-gray-600">
<%= link_to notification.item.content.truncate(100), notification.item, class: "underline text-blue-600 hover:text-blue-800 font-medium" %>
</p>
<p class="text-sm text-gray-400 mt-1">
<%= time_ago_in_words(notification.item.created_at) %> ago
</p>
</div>
<% if notification.item.image.attached? %>
<div class="flex-shrink-0">
<%= image_tag url_for(notification.item.image), class: 'w-20 h-20 object-cover rounded-lg' %>
</div>
<% end %>
</div>
Upvotes: 0
Reputation: 8459
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
Upvotes: 1
Reputation: 171
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) %>
Upvotes: 2
Reputation: 91
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
Upvotes: 5
Reputation: 369
Also try @object.image.service_url
. This will give you the url where the image is saved. I.E. url to amazon s3 storage.
Upvotes: 19
Reputation: 369
I got it to work with rails_blob_url(@object.image)
. Notice I am calling _url not _path with the helper.
Upvotes: 2
Reputation: 101
Please follow this for fetching images( in case if you are using has_many_attached)
Model.images.map{|img| ({ image: url_for(img) })}
Upvotes: 4
Reputation: 11183
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)
Upvotes: 53