How to display image from private folder inside View? - ruby-on-rails

I need a quick tip on something which seems really simple. I have some pictures inside private folder and would like to display them inside my View.
The only solution I found was this:
def show
send_file 'some/image/url', :disposition => 'inline', :type => 'image/jpg', :x_sendfile => true
end
I've read that :disposition => 'inline' should not trigger image download and allow me to display it inside my View. The problem is that each time I trigger show action, image download is automatically activated and it is automatically downloaded. View for show action is not displayed.
How can I display that image inside my View? Thank you.

The way I do it, and I'm not saying it's perfectly by the book, is I make a root for images and an action in the controller to render it.
So, for instance, in routes.rb
match '/images/:image', to: "your_controller#showpic", via: "get", as: :renderpic
In your controller:
def showpic
send_file "some/path/#{params[:image]}.jpg", :disposition => 'inline',
:type => 'image/jpg', :x_sendfile => true # .jpg will pass as format
end
def show
end
And in your view
<img src="<%= renderpic_path(your image) %>">
Here is a working example, with fewer parameters on "send_file"
def showpic
photopath = "images/users/#{params[:image]}.jpg"
send_file "#{photopath}", :disposition => 'inline'
end

I think the problem is type. From documentation:
:type - specifies an HTTP content type
So the proper HTTP content type should be image/jpeg instead of image/jpg, as you can see here. Try with:
:type => 'image/jpeg'
You also can list all available types coding Mime::EXTENSION_LOOKUP into a rails console.
Example:
Controller
class ImagesController < ApplicationController
def show_image
image_path = File.join(Rails.root, params[:path]) # or similar
send_file image_path, disposition: 'inline', type: 'image/jpeg', x_sendfile: true
end
end
Routes
get '/image/:path', to: 'images#show_image', as: :image
Views
image_tag image_path('path_to_image')

You would need to have the view use an image_tag to display on the view.
Similar question was raised here: Showing images with carrierwave in rails 3.1 in a private store folder

Related

How to download file with id params?

Hello I try to download a jpeg image on rails by verifying that the Post exists and by recovering its id in parameter.
I try something but i got a error... I show you:
def download
send_file '/public/uploads/posts/#image/image.jpg', :type => 'image/jpeg', :disposition => 'attachment', :x_sendfile => true
end
private
def set_image
#image = Post.find(params[:id])
end
In my controller I have to in my routes get download.
And my link_to is:
<%= link_to "Download", download_posts_path %>
But rails say to me "Couldn't find Post without an ID".
I don't understand why... He dont't have the id but I dont't know why ?
Assuming you use set_image in a before_action filter.
First you should pass the post instance or id to your route helper :
If your route takes a param e.g. /posts/:id/download :
<%= link_to "Download", download_posts_path(#post) %>
<%= link_to "Download", download_posts_path(#post.id) %>
If not you can pass it with a query parameter e.g. posts/download/?id=1
<%= link_to "Download", download_posts_path(id: #post.id) %>
Both solution will provide you a params[:id] in your controller. Otherwise params[:id] will be nil and find raises an error.
Then there's something wrong in the download action as #DileepNandanam pointed out. You're not using your Post instance (#image) at all, you're just passing send_file a string containing "#image", not the variable but just a string. You may want to use interpolation to build a valid path to your image. For example if your #image has a :name which could be "image.jpg" you would do it like this:
send_file "/public/uploads/posts/#{#image.name}"
Or you could name your images with the post id like 13.jpg then you'll do :
send_file "/public/uploads/posts/#{#image.id}.jpg"
Or even create separate forlders with post's ids :
send_file "/public/uploads/posts/#{#image.id}/image.jpg"
send_file "/public/uploads/posts/#{#image.image_file_name}/image.jpg", :type => 'image/jpeg', :disposition => 'attachment', :x_sendfile => true
The method image_file_name may varies depends on the attachment you have specified on model
A better way is to use the url for attachment like
send_file #image.image.url(:original)

Getting ActionController::MissingFile when trying to force a download (vice open) with send_file

I am using rails 4.x with paperclip. I want to ensure that when the user clicks on a link to download a paperclip attachment, the file is downloaded instead of opening up.
The link I was using that would open or save depending on the browser configuration was
<%= link_to image_tag("save.gif", document.doc_file.url, :target => "_blank" %>
That link will sometimes open the file instead of downloading.
I set up a method of
helper_method :download
def download
#document= Document.find(39)
send_file ("http://localhost:3000/images/39/Medical_Opportunity_EvaluationForm.pdf?1458068410"),
:filename => #document.doc_file_file_name,
:type => #document.doc_file_content_type,
:disposition => 'attachment'
end
I hardwired the url for testing. I had also tried with send_file ("http://localhost:3000#{#document.doc_file.url}") and send_file (#document.doc_file.url). NEither worked.
My link to that is
<%= link_to image_tag("save.gif"), download_path(document.id) %>
routes.rb has
match 'documents/download/:id' => 'documents#download',via: [:get, :post], :as => 'download'
When I click on the download link, I get an error of
ActionController::MissingFile in DocumentsController#download
Cannot read file http://localhost:3000/images/39/Medical_Opportunity_EvaluationForm.pdf
Rails.root: C:/Users/cmendla/RubymineProjects/technical_library
Application Trace | Framework Trace | Full Trace
app/controllers/documents_controller.rb:17:in `download'
If I put the URL into an address bar on a browser, it works. i.e. `http://localhost:3000/images/39/Medical_Opportunity_EvaluationForm.pdf'
The send_file method accepts the physical location of the file on your server, not public URL. So something like the following should work, depending on where the PDF file actually resides:
send_file "#{Rails.root}/public/images/39/Medical_Opportunity_EvaluationForm.pdf",
:filename => #document.doc_file_file_name,
:type => #document.doc_file_content_type,
:disposition => 'attachment'
If this is a paperclip document, the path method should work:
send_file #document.doc_file.path,
:filename => #document.doc_file_file_name,
:type => #document.doc_file_content_type,
:disposition => 'attachment'
See the docs for more info.

Rails 4 throws image has errors when i use send_data with image magick image

I have an issue when I send an image with send_data method in Rails.
I have a controller with a helper method that sends the image data to an image tag
class HomeController < ApplicationController
helper_method :img
def index
end
def img
image.resize '1600x900'
image.rotate '180'
File.open(image.path, 'r') do |f|
send_data f, filename: 'gift_front.jpg', :type => 'image/jpeg', :disposition => 'inline'
end
end
end
And the view is just this line:
<%= image_tag img, alt: 'Loading Image...', title: 'image' %>
But when the page is loaded in the browser I get this error:
The image “http://localhost:3000/” cannot be displayed because it contains errors.
I use rails 4.1.2 and ruby 2.2.2. The rails log doesn’t show any errors. I need to get a functionality where image data is sent to the browser, from an image out of the project, and this looks like the only solution, but I can't find a solution to this error.

How to download file with send_file?

Can someone enlighten me how can I download file with send_file?
I have a file image.jpg inside app/assets/images. I've tried this in my controller:
def download
send_file ("#{Rails.root}/public/images/image.jpg")
end
def download
send_file ("#{Rails.root}/assets/images/image.jpg")
end
def download
send_file ("#{Rails.root}/images/image.jpg")
end
def download
send_file ("/public/images/image.jpg")
end
def download
send_file ("/assets/public/images/image.jpg")
end
def download
send_file ("/assets/images/image.jpg")
end
For each path it says:
ActionController::MissingFile in HomeController#download
Cannot read file 'some_path'
What could be a problem here? Thanks!
Try:
IMAGES_PATH = File.join(Rails.root, "public", "images")
def download
send_file(File.join(IMAGES_PATH, "image.jpg"))
end
In your view =>
<%= link_to "click here to download", signed_feeds_pdf_path(:feed_image_path => feed_image.feedimage.path), target: '_self' %>
In your controller =>
def pdf
file_name = params[:feed_image_path].split('/').last
#filename ="#{Rails.root}/public/uploads/feed_image/feedimage/#{file_name}"
send_file(#filename ,
:type => 'application/pdf/docx/html/htm/doc',
:disposition => 'attachment')
end
soo simple......
well, i suggest you to move your file to public folder. Anyway , do this
send_file(Rails.root.join('app' , 'assets', 'images', 'image.jpg'))
We need to specify the mine type so that it will cache.
send_file ("#{Rails.root}/public"+image.image_path), :type => "image/jpeg", :disposition => 'inline'
For anyone still looking for an answer, send_data and send_file won't work when responding to ajax calls. Instead, try submitting a form or using <a href=..> to call the controller method and download a file.

How to display images in Rails without plugins like Paper Clip?

I'm trying to display images using my web application written in Rails. I've come across solutions like PaperClip, Attachment Fu etc; but they modify my data model and require to save the image through UI. The problem is that, the images content is not stored using Rails, but a Java Servlet Application. Is there a way to just display the blob content of image to my View.
-Snehal
class ImagesController < ApplicationController
caches_page :show
def show
if #image = Image.find_by_file_name(params[:file_name])
send_data(
#image.file_data,
:type => #image.content_type,
:filename => #image.file_name,
:disposition => 'inline'
)
else
render :file => "#{RAILS_ROOT}/public/404.html", :status => 404
end
end
end
map.connect "/images/*file_name", :controller => "images", :action => "show"
Or something like that.

Resources