Download and redirect in rails - ruby-on-rails

I have to put a link to download pdf file on my Rails app and it works.
But after download I don't want users in .../download_pdf.fr page but I want to redirect them in index.
I tried to put redirect_to root_path in download method in my controller but download didn't work with that.
If you have any idea.
Thank you a lot
Routes
get 'download_pdf', to: "home#download_pdf"
Controller
def download_pdf
send_file "#{Rails.root}/app/assets/images/file.pdf", type: "application/pdf", x_sendfile: true
end
View
<%= link_to "Télécharger", download_pdf_path, class:"button1" %>

Related

Download a PDF file with ruby-on-rails, error message

I followed the steps setting a link to download a PDF file on a preview question about that.
Problem is, when I click on the download button, it open a window to show the PDF, but the PDF doesn't show up...
When I open or download it, I got this message "File type unknown (application/octet-stream) is not supported"
What's wrong?
Thank you
Here, how i set it up:
Controller
class HomesController < ApplicationController
def index
end
def download_pdf
send_file(
"#{Rails.root}/app/assets/docs/dossier_de_presentation_lvsl.pdf",
type: "application/pdf"
x_sendfile: true
)
end
end
routes.rb
get 'download_pdf', to: "homes#download_pdf"
view
<%= link_to "Download Pdf", "/assets/dossier_de_presentation_lvsl.pdf", :class => "themed_text", class: "btn btn-lg btn-custom" %>
Your controller action is not used at all. Browser tries to download file from the following path public/assets/dossier_de_presentation_lvsl.pdf.
If you want to download it through the controller action. You should set your application in following way:
In your routes:
get '/download_pdf', to: 'homes#download_pdf', as: 'download_pdf'
In your controller:
def index
end
def download_pdf
send_file(
"#{Rails.root}/app/assets/docs/dossier_de_presentation_lvsl.pdf",
type: "application/pdf",
disposition: 'attachment', # 'inline' if you want to show PDF in the browser instead of downloading it directly
x_sendfile: true
)
end
end
In your view:
<%= link_to "Download Pdf", download_pdf_path(format: :pdf), :class => "themed_text", class: "btn btn-lg btn-custom" %>
Or if you want, you can put your PDF directly to public folder in your rails app eg. to public/pdf/dossier_de_presentation_lvsl.pdf
and than you can use just a link:
Download PDF
But you can use this only if your PDF can be downloaded by everyone without any authentication etc. On the other hand you would not have to bother with the controller action and routes, it will be handled for you automatically.

External link to controller won't render .js.erb file Rails 4

I can render a .js.erb file following an ajax request, but if I type this url into the browser:
http://localhost:3000/posts/11
with a Post model that has a show action defined as
def show
respond_to :js
end
and a corresponding show.js.erb file, I get the following error:
ActionController::UnknownFormat at /posts/11
ActionController::UnknownFormat
I want to be able to generate links for users to copy and paste so that they can link to posts, but I can't get passed this error.
You need to specify format within your url:
http://localhost:3000/posts/11.js
To generate such a route "rails way" pass format option to path:
link_to post.title, post_path(id: post.id, format: :js)

Ruby on Rails send_file doesn't work until i refresh the page?

I am working on a Rails server which I can download my locally stored movies and anime etc from. This is kind of working but when I click the download link I have to refresh the page in order for the download to actually start.
This is the controller that handles the download:
class DownloadController < ApplicationController
def index
#title = params[:title]
#name = params[:name]
#path = '/media/sf_Anime,_VN,_LN/Watching, not watched yet/'+#title+'/'+#name
send_file( #path )
end
end
and this is the link that links to that controller:
<% #episodes.each do |x| %>
<p> <%= x %><%= link_to " Download",
{controller: 'download', action: 'index', title: #title, name: x } %> </p>
<% end %>
edit:
I did some testing today and noticed that the download links work instantly if i try to send a smaller file (text or image). I also noticed that the download links actually works for the movies aswell but it takes 20-30 seconds for the download to start.
Do you have any idea of what would cause this delay?
Are you using turbolinks? Turbolinks apparently doesn't play nicely with send_file (https://github.com/rails/turbolinks/issues/182). Try adding "data: { no-turbolink: true }" (or "'data-no-turbolink'=>true") in the link_to helper, e.g.:
<%= link_to "Downloadable File", downloadable_file, data: { no-turbolink: true } %>
See also: Rails 4, asset pipeline causes user downloadable files to be downloaded twice, rails won't send_data as file, Ruby on Rails send_file, code in controller action running twice
Edited to reflect comment below. I would simple add a concern for handling downloads and then use
include Concerns::Downloads
to handle your download request. the routes.rb would look like this.
resources :movies do
member do
post 'download'
end
and in the view
<%= link_to 'Download', {:controller => 'movies', :action => 'download'}, {:method => :post } %></a>
Move the file to public folder
add only file name into link_to
<%= link_to "Downloadable File", "/"+filename, %>
Try setting the disposition to attachment in send_file:
class DownloadController < ApplicationController
def index
...
send_file( #path, :disposition => 'attachment' )
end
end
The issue may be that your browser is trying to open the file itself - :disposition => 'attachment' prompts the browser to download the file, even if it thinks the file is something that it can open.

How do I add different types of GET routes that require parameters in Ruby on Rails

I have a list of users being displayed, you can click on "Show user" or "PDF" to see details of that user in HTML or as a PDF document. The show was automatically created with scaffolding, now I'm trying to add the option to view it as a PDF. The problem is adding a second GET option, if I pass the user along as a parameter, it is assumed to be a POST and I get an error that the POST route does not exist. I am not trying to update the user, just to show it in a different way, basically to add a second "show user" option.
How do I tell it that I want a GET, not a POST? Is there an easier way to do what I am trying to do? Thanks.
Please, create a controller like this:
class ClientsController < ApplicationController
# The user can request to receive this resource as HTML or PDF.
def show
#client = Client.find(params[:id])
respond_to do |format|
format.html
format.pdf { render pdf: generate_pdf(#client) }
end
end
end
Please, update route.rb file, action name with post and get, like below :
match 'action_name', to: 'controller#action', via: 'post'
match 'action_name', to: 'controller#action', via: 'get'
More info please read this link : "http://guides.rubyonrails.org/routing.html"
you haven't posted any code or details, so I am guessing you want something like this:
routes
resources :users
controller
class UsersController < ActionController::Base
def show
#user = User.find(params[:id])
respond_to do |format|
format.html # show.html.erb
format.pdf # handle the pdf response
end
end
end
view file in views/users/show.pdf.prawn
prawn_document() do |pdf|
#user.each {|r| pdf.text r.id} # will print user id of the user
end
The way above example will work is, if something visits the following URLs, they will get html file:
localhost:3000/users/1 #html is the default format in rails
localhost:3000/users/1.html
but if they visit .pdf, they will be served a pdf format.
localhost:3000/users/1.pdf
If the above assumptions are correct, then check prawn or wicked_pdf pdf gem. the above example uses prawn
Checkout this link http://apidock.com/rails/ActionController/MimeResponds/InstanceMethods/respond_to. You can add a new MIME type and pass on the :format as pdf in all your rails routes.
Hope this will help.
And for the POST-request check your
config/routes.rb
There shoud be a few routes already, so you can infer the route you need.
In your link you can pass an additional parameter called format for pdf. For e.g.
<%= link_to 'Display in PDF', "/user/pdf", :format => "pdf" %>

Getting a loop when using link_to :back

I have this structure for the table course:
Search page -> Result Page -> Edit Page -> Show page
When i go from result page to a specific course edit page, i edit it, and end up on the show page, but when i hit back, i get a loop from show to edit, and back to show and so on.
I want the edit page to back to the result page if it came from there.
im using this on both:
<%= link_to "Back", :back %>
When you actually update your record having edited it you're likely to be doing a redirect from an update action via a put request to show. Even if you're not, and if you're defying convention and updating from the show action, you're trying to navigate to a post action with a get request. If I understand you correctly, you want to be able to edit from either the search result or the show page. What you should do is define a method that allows you to store a location in the session on demand. Put it in the application controller and it will be available to all of your controllers.
# copy this into your application_controller.rb file :
private
def store_location
session[:return_to] = request.request_uri
end
#copy this to the top of your item_controller.rb file:
before_filter :store_location, :only => [:search, :show]
#replace your <%= link_to "Back", :back %> with
<%= link_to 'back', session[:return_to] -%>

Resources