How to download file with send_file? - ruby-on-rails

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.

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)

Download Blob file in Rails App is shown inline and not attached

I get a blob from a function in my oracle Datenbank. Users of my Rails App should be able to download these BLOB. My Problem is, that after clicking on download, the BLOB file is shown inline in the browser, but it should be download as a file.
link:
= link_to export_pldw_plausibility_path, :class => "btn btn-primary
action-button" do
%span.glyphicon.glyphicon-pencil
%span.hidden-xs
= "Export"
route:
resources :pldw_plausibilities do
get 'export', on: :member
end
controller:
def export
send_data PldwPlausibility.export(params[:id]), :filename => "test.BLOB",
:disposition => 'attachment'
end
Model:
def self.export(id)
return plsql.pld.pld_mdc.exportMDOC('PLD_PLAUSIBILITY', id.to_i)
end
Screenshot
Sorry!
Adding :target => "_blank" to the link solves this Problem..

How to display image from private folder inside View?

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

Export CSV file (without changing the page)

show.html.erb
<%= link_to "Export", {:action => :export}, :method => :post%>
record_controller.rb
def export
csv_file = CSV.generate({}) do |csv|
csv << #data_filtered.first.keys
#data_filtered.each do |hash|
csv << hash.values
end
end
send_data csv_file, :type => 'text/csv; charset=iso-8859-1; header=present', :disposition => "attachment; filename=tester1.csv"
end
I am wondering how to do this because #data_filtered is an instance variable sent to show.view but it no longer exists when I click export (this is the data i want to export to a .csv). Is there a way to pass this data through link_to? I am also anticipating the issue that this is going to change the view which I dont want to do.
Here are two basic approaches:
In your 'show' method, save what's in #data-filtered to your model. Then you can find it again in the 'export' method.
Or, you have to send it all down to the client, and the client will have to send it all back.

Rails; save a rendered views html content to file

I'm trying to create a view with a download link to download the html source?
#Peter 's solution worked for me. Here is a code sample:
View:
<%= link_to 'download this page', object_path(#object, :download => true) %>
Controller:
def show
# ...
if params[:download]
send_data(render_to_string, :filename => "object.html", :type => "text/html")
else
# render normally
end
end
You can use render_to_string instead of render, which will give you the page, then to download it use send_data.
More on render to string here, and more on send_data here.

Resources