How to display image in rails with ActiveStorage - ruby-on-rails

Rails: 6.1
Following the basic steps in the documentation of ActiveStorage I have added a avatar field for my User model and upload seems to be successful. But when I want to display #user.avatar I get a url for the image but the url seems to be 404. The image is not displayed.
Here is my image tag:
<img src="<%= image_path(url_for(#user.avatar)) %>" alt="Avatar for <%= #user.username %>">
<%= image_tag #user.avatar, class: 'user-image', alt: "Avatar for #{#user.username}" %>
Both of these are failing. Rendered HTML is here:
<img src="/rails/active_storage/blobs/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaHBCZz09IiwiZXhwIjpudWxsLCJwdXIiOiJibG9iX2lkIn19--569f9d466f5dd0d4917db040f0f87d948c0af667/paddle.png?locale=en" alt="Avatar for Someone">
Looking at the path, paddle.png is the image I uploaded and I assume upload is okay. But why doesn't it display?

Try this:
<%= image_tag #user.avatar.to_s, class: "user-image" %>

Okay, finally I found what was wrong. First thing ActiveStorage is not compatible with UUID models. What's more for a given 12hefhs-342jfsoeif-senfs-senfks UUID it takes the first consecutive digits and uses it as ID. Which is in my opinion a big issue. We don't get any error message like we do for other rails models when we try to save UUID in bigint (default id) field. To overcome this problem I had to add these migrations in this gist
Then the other problem was that I have a regex to redirect all requests to locale version of that same path. Like this:
get "/*path",
to: redirect("/#{I18n.default_locale}/%{path}", status: 302),
constraints: { path: /(?!(#{I18n.available_locales.join("|")})\/).*/ },
format: false
and this was redirecting image urls as well...
Removing this solves the problem. But introduces another one... How to redirect...

Related

problem with <img image_path> vs <image_tag> with cloudinary

I wish to use the Image_tag in rails 5.2 like this:
<%= image_tag(#character.picture) %>
I get the following error:
"Can't resolve image into URL: undefined method `to_model' for #<PictureUploader:0x00007f619c7fd000>"
I was successfully using
<img src="<%= image_path(#character.picture) %>">
I am unsure why these two bits of code generate different results. Am I missing some quality with the image_tag? I can easily cut my losses and use the image_path option but aesthetically I would prefer to not have more html than needed in my code and wish to know why there is a difference in these two bits of code.
Try this .......
<%= image_tag(#character.picture.url) %>
Hope this will help you.

Ruby on Rails Youtube Image Embed

I'm trying to accomplish this without any plugins.
Basically we just use the standard copy and paste method for embedding Youtube onto our website... the problem, then, is that if we try to share a post of ours with video on facebook... the image thumbnail isn't there.
The thumbnail is always saved in this format:
http://i1.ytimg.com/vi/7Uz1hfza55k/default.jpg
...with the video id coming just before "default.jpg"
I already have three "photo" slots in the database for each post.
So I'd like to do something like this:
<%= image_tag("<%= daily.photo .html_safe %>") %>
I'm just not sure of the proper syntax so that it gets the photo URL for that particular post.
What I want it to return in the end is something like this:
<%= image_tag("http://i1.ytimg.com/vi/7Uz1hfza55k/default.jpg") %>
Getting the URL, of course, from the "photo" section of each post's database entry.
For extra credit maybe you could explain a way that I could arrange it so that all the person writing the articles would have to do is enter the video code and it would be automatically inserted in:
<%= image_tag("http://i1.ytimg.com/vi/CODEHERE/default.jpg") %>
Thank you for your time.
Edit:
Just so we're clear this works:
<img src="<%= #daily.photo %>">
But this doesn't work:
<%= image_tag("<%= daily.photo .html_safe %>") %>
They should be the same as far as I know... but they don't work the same. If worse comes to worse I'll just go with img src...
<%= image_tag(#daily.photo) %>
In ERB, <%= stuff %> means: everything inside this is good old plain ruby. There is no need to use the tag twice, as #daily.photo is just an argument for the image_tag method.

How do I create a default avatar if the avatar file does not exist?

I used paperclip to let users upload their avatars. Everything works fine.
I want to show a default image if the user didn't upload an avatar. I used this code in my view:
<%=
if File.exist?(user.avatar.url)
image_tag user.avatar.url(:large)
else
image_tag "default-avatar.png"
end
%>
but it doesn't show the default image.
I put the default-avatar.png in app/assets/images/.
What am I doing wrong?
EDIT
I followed the instructions oldergod mentioned in comments, but still the uploaded avatars don't show up.
I finally put it to work, using user.avatar? like this:
<%=
if user.avatar?
image_tag user.avatar.url(:large)
else
image_tag "default-avatar.png"
end
%>
I think the problem is that File.exist? needs a path, not a url or something.

wicked_pdf image rendering

how do I get images of a product to show in pdf?
I have this code in view file
<div id="img-slide">
<% for asset in #car.assets %>
<%= image_tag(asset.asset.url(:medium)) %>
<% end %>
</div>
and it shows all images for this car.
but if I use the same code in show.pdf.erb then instead of images I got only question marks.. like the image missing thing.
So, is there a way to get them on paper? Thanks.
p.s. there is what console is showing
***************WICKED***************
Asset Load (0.2ms) SELECT `assets`.* FROM `assets` WHERE (`assets`.car_id = 29)
Carmodel Load (0.2ms) SELECT `carmodels`.* FROM `carmodels` WHERE `carmodels`.`id` = 28 LIMIT 1
Rendered cars/show.pdf.erb (255.2ms)
"***************/usr/bin/wkhtmltopdf -q - - ***************"
update
<%= pdf_image_tag('/public/system/assets/163/medium/2011_lincoln_navigator_l_angularfront.jpg', :style=>"margin:0px;padding:0px", :width=>"300", :height=>"240")%>
this code shows how the link should look like in html, with this code I can render one photo of the car, but it will be the same for all cars, so I didn't do much.
the 163 number is the id of assets that is assigned to car, here I keep one image with more sizes(thumb, medium, large..) and I got 5 maps with different numbers for one car. So I have lots of maps with numberes like this as I have at least 5 photos for each car. each car have 5 assets. In show.html I can see them, but not in pdf. I did put this in application helper:
def pdf_image_tag(image, options = {})
options[:src] = File.expand_path(RAILS_ROOT) + '' + image
tag(:img, options)
end
but this is only for images that you have on your server and will be the same for all cars, how can I get at least one image of each car to show in pdf? Pleaseeeee. help!!!
Version 0.7.9 is
<%= wicked_pdf_image_tag 'myfile.jpg' %>
It basically returns the absolute path on the file system:
file:///path/to/image/myfile.jpg
Also see: https://github.com/mileszs/wicked_pdf
Instead of using wicked_pdf_image_tag helper it's possible to use image_tag and image_url rails helpers together to get absolute path to image (this is what required for wicked_pdf gem):
image_tag image_url('dir/image.png')
here dir/image.png is image path relative to standard location in rails app (app/assets/images for images).
ok, so I found the answer
the <%= image_tag(asset.asset.url(:medium)) %> code generates the url to the image that in html will look like <img alt="2012_bmw_7_series_gearshift" src="/system/assets/174/original/2012_bmw_7_series_gearshift.jpg?1318267462"> so my images starts in system map and all I had to do is to write a method in application_helper.rb like this:
module ApplicationHelper
def pdf_image_tag(image, options = {})
options[:src] = File.expand_path(RAILS_ROOT) + '/public' + image
tag(:img, options)
end
end
this way wiked_pdf will know that image tag called pdf_image_tag will start from system folder in public and the final code for the pdf.html.erb will be:
<% for asset in #car.assets %>
<%= pdf_image_tag(asset.asset.url(:medium), :style=>"margin:0px;padding:0px", :width=>"250", :height=>"200")%>
<% end %>
was easy, but still took me a few days to figure it out. Nice day.
The only thing that worked for me is to use this:
<%= image_tag wicked_pdf_asset_base64('logo') %>
While the answer of #tap349 worked a bit for me, I had to do something completely different for images already stored in the project.
So, for images uploaded by the users, I use the mini_magick gem and in my views I have (I use slime syntax):
= image_tag image_url(picture.url(:medium))
For images already stored in the project I had to manually create the absolute path, by returning the image location and joining it with the request protocol and host like this (I use Webpacker and my images are in app/javascript/images):
= wicked_pdf_image_tag URI.join(request.base_url, asset_pack_path('media/images/logo.png'))
In another post I saw this command that helped me to see if the path existed or not, you can try it in the ruby console:
Webpacker.manifest.send(:data).keys.grep /logo/

Rails PaperClip Attachments, knowing if there's a image thumbnail?

I'm using Rails 3 paperclip and allow users to upload attachments to the attachment model.
If the file is an image, the app generates image previews. If the file is not, it only uploads the file (no image previews).
Now I would like to display a list of all the attachments in the DB. So I use attachment.attachment(:large) and that works fine for image attachments, but errors (obviously) for non-image attachments.
What's a good way to check if it's an image attachment or not? If not, I'd like to display a standard static image. Any suggestions? thanks
This is what I did in my view:
<% if !(#attachment.attachment.content_type =~ /^image/).nil? %>
<%= image_tag #attachment.attachment.url(:small) %>
<%end%>
This assumes that your model is attachment, and my file, I so called attachment.
So you could do something like:
<% if !(#attachment.attachment.content_type =~ /^image/).nil? %>
<%= image_tag #attachment.attachment.url(:small) %>
<%else%>
<%= image_tag "/path/to/image/default.png" %>
<%end%>
Check attachment.attachment.attachment_content_type
For example, it might be: "image/jpeg"
You can create a migration that adds a attachment_content_type field of type string to your attachment table. When you create an attachment, paperclip stores the type of the file in that field. You can then check if the file type is something like "image/jpeg".
Maybe you could use default_url option? That would be shown if the real thumbnail doesn't exist.
http://www.suffix.be/blog/default-image-paperclp

Resources