Rails: Accessing image files after being uploaded - ruby-on-rails

I am writing a Ruby on Rails 5 app. I just learned how to upload an image without using paperclip,carrierwave, or refile. I have used refile in the past but for this app, I wanted to learn how to do it with out those third party gems. And it was not that difficult to do. I have successfully uploaded a file. My problem is accessing the image afterwards! I thought this would be rather simple. But NO!
I have image files being uploaded to "/public/images/page/image.jpg"
I have added "/public/images/page" to the assets path in app/initializers/assets.rb
I have tried straight img tag like this:
<img class="pic left" src="/public/images/page/mars01.jpg" alt="Mars01" />
I get a "(No route matches [GET] "/public/images/page/mars01.jpg")" error.
I have tried:
<%= image_tag "/public/images/page/#{#page.image}", class: 'pic left' %>
basically the same as tag, get same results. Also tried:
<img class="pic left" src='<%= image_path "#{#page.image}" %>' />
still get routing error, but only looking in "/images" directory. I am still in development mode, so I thought that image_path would be the correct path.
What is the correct way of accessing an image, that was just uploaded to a directory outside of the asset pipeline? That will work in development or production env? I really thought this would be straight forward.

You don't have to give the whole path to image within image_tag, you just give the image name with the sub directory if it exists.
So try <%= image_tag "#{#page.image}", class: 'pic left' %>.
And please read more about asset pipeline.
http://guides.rubyonrails.org/asset_pipeline.html

Here is what I ended up doing for anyone interested.
in my controller I did this:
# default to development go to app/assets/images
path = Rails.root.join('app', 'assets', 'images', uploaded_io.original_filename)
if ENV['RAILS_ENV'] == 'production'
# change only if in production to public/assets/images
Rails.root.join('public', 'assets', 'images', uploaded_io.original_filename)
end
File.open(path, 'wb') do |file|
file.write(uploaded_io.read)
end
Based on RAILS_ENV; if development, images will go to app/assests/images folder; if in production they go to public/assets/images.
And using a straight forward image_tag:
<%= image_tag "#{#page.image}" %>
worked like a charm. Well at least I know it works in development setting.
Thanks to those that responded. (Mat, and Nagasaki)

Related

"/assets" missing from Rails asset_path in emails. It's different in two environments

I have an image_tag helper that looks like this in a layout:
= image_tag asset_path("logo/logo-02.jpg", :digest => false), alt: 'Some Logo'
In a staging app (preview app) on heroku, the asset_path is converted to this (correctly):
https://s3.amazonaws.com/media-dev.some_host.com/assets/logo/logo-02.jpg
However, in production, it's missing the assets part of the path and it's this:
https://s3.amazonaws.com/media-dev.some_host.com/logo/logo-02.jpg
Any initial thoughts on where the problem is? I think the asset_path helper is different for some reason, but I'm not sure where to look.
We are using a CDN and in short, the images are located in /assets/logo and that's what we want the URL to be.
It's only broken in emails as well send by ActionMailer. Any thoughts on where the production configuration for ActionMailer might be incorrect?

Using URL variables in 'show' view

I'm working on a Ruby on Rails project that uses Paperclip for file uploads, S3 for storage, and does some back-end image conversion using Blitline. The result of the conversion gives the original and a file called upload.png in my S3 bucket alongside the original.
So, after conversion I've got two files something along the lines of:
myaws.amazonaws.com/mybucket/model_id/original.pdf and
myaws.amazonaws.com/mybucket/model_id/upload.png
Ideally, I would like to keep the original at hand in my bucket case my user needs to download it again, or if we need to do another conversion for some reason.
Is there a method similar to <% = image_tag #attachment.url %> that will specify the file 'upload.png'?
Edit (More info:)
I did attempt <% = image_tag #attachment.url, :format => :png %> though it does not work. Seems as if rails is still trying to pull it up as a PDF
Have you specified a style for your attachment? If you have one, let's say xyz then you can get the url <% = image_tag #attachment.url(:xyz) %>

Asset names passed to helpers should not include the "/assets/" prefix

I have a rails app in production with apache2 and passenger. But some of my images didn't appeared so i changed the path inside the 'image_tag' like this:
<%= link_to image_tag("/assets/#{product.image_url}", {:title => "Push it into cart!"}), line_items_path(product_id: product), method: :post %>
After this all work fine in production. But when i try in development, i got this error:
Sprockets::Rails::Helper::AbsoluteAssetPathError in Store#index
Asset names passed to helpers should not include the "/assets/" prefix. Instead of "/assets/cs.jpg", use "cs.jpg"
What i should do to make it work in both enviroments?
image_tag works without using /assets/ path as long as you have the asset pipeline enabled (which is the default) and your image is in app/assets/images/ folder. If your image is outside that folder it won't get precompiled so you'll have to add it to the asset precompilation, in your config/environments/production.rb add
config.assets.precompile += ['image.jpg']
I think that for your problem you shouldn't store the images of your products in the assets folder as this is used for the application images not for you content (models) images, those should be stored in the public folder public/uploads is commonly used for that by gems like paperclip
You should never use /assets/ prefix, it's possible that you just need to precompile assets for production.
rake assets:precompile RAILS_ENV=production
It also depends on where are you using the said asset, for example, when using it in stylesheet you should use image-url('image.jpg') rails css helper. When using it inline in the view, you use the image_tag helper, as you have.

How do I call images in a subdirectory? Rails 4 app breaks when I push to production

I have a rails app that performs fine in development but as soon I as I push to production it breaks. It was working fine until I added a /gifs subdirectory to the /images directory.
I'm pulling a random gif in the directory and displaying it.
<%= image_tag "assets/gifs/#{rand(10)}.gif" %>
I've also tried
<%= image_tag "gifs/#{rand(10)}.gif" %>
and
<%= asset_url("gifs/#{rand(10)}.gif") %>
But nothing is working. How should I structure this?
Have you tried /assets? Like this:
<%= image_tag "/assets/gifs/#{rand(10)}.gif" %>
I would start without the interpolation just to make sure you can see the image and then add the variable.
EDIT: Sorry for the quick shot, I have it like this in mine and thought that might fix it. I think what you actually need is to tell your config/environments/production.rb that you want to precompile those folders also... in development, it will happily include everything for you, but in production, it needs to be more selective and rigid (there are various explanations for that elsewhere).
Try this:
open config/
look for this line: config.assets.precompile and add your subfolder to it.
config.assets.precompile += [ 'gifs/*.gif']
If you decided to organize your other assets into controller-related subfolders (I like that), you need to add those here too: (example: local, resources, projects, shared subfolders)
config.assets.precompile += [ 'local/*.css', 'resources/*.js', 'projects/*.js', 'shared/*.js', 'ui/*.js', 'admin.a pp.js', 'jquery.tablesorter.min.js', 'date-picker.js', 'date_extras.js', 'jquery.tablesorter.min.js']
Hope this helps!

How do you access files stored in the tmp directory?

I'm using CarrierWave to upload images to my web page. Currently, I have it working with Amazon S3 and Heroku. However, I would like to be able to test it on my machine using localhost. Again, I have this working. However, I'm storing the uploaded photos in my apps tmp directory located at:
Users/.../app/tmp/uploads.
When trying to display an image I get a broken link. I've been using:
<img src='<%= bucket.path %>'/>
to display images, and it has been working on Heroku. On localhost I get this error:
ActionController::RoutingError
(No route matches [GET] "/Users/.../app/tmp/uploads/pic.jpeg")
I'm not sure what to do really, I thought providing the path would be enough. Thanks for the help!
Are you using fog? This reply assumes you are.
in /config/environments/development.rb you should be able to set the following:
config.uploadsURL = "http//localhost:3000"
config.serve_static_assets = true
in /config/initializers/carrierwave.rb:
if Rails.env.production?
# your aws config stuff
else
config.storage = :file
end
in a view (unless I am forgetting something) you should then be able to just:
<%= image_tag(image.imgUpload.mini) if image.imgUpload? %>
where 'mini' is a carrierwave version and imgUpload is the mount you defined in your model:
mount_uploader :imgUpload, ImageUploader
of course, you should be able to test it on localhost while also using AWS storage. It might be simpler to just change your /config/environments/development.rb from:
config.action_controller.asset_host = "//#{ENV['FOG_DIRECTORY']}.s3.amazonaws.com"
to
config.action_controller.asset_host = "//your-test-bucket.s3.amazonaws.com"
and keep using AWS while running on localhost.

Resources