I've been trying to do this for a long time but can not seem to get around it.
For url's ending with .pdf I want the asset_host to fetch files locally.
So I do the following in my development.rb file
config.action_controller.asset_host = Proc.new { |source,request|
source.format.to_s.match(/pdf/) ?
"file://#{Rails.root.join('public')}" :
"#{request.protocol}#{request.host_with_port}"
}
But this give me errors like:
private method `format' called for "/stylesheets/css3buttons/reset.css?1304745651":String
Question
What is the best way in rails3 to detect the format of the url request??
Update
I've tried the source, request.media_type and request.format but none of them fetch the PDF!!
Below the logs are shown. I had added debug statements for each of the three above.
config.action_controller.asset_host = Proc.new { |source, request|
print "Source: " + source
print "\n"
print "request.media_type: " + request.media_type
print "\n"
print "request.format: " + request.format
print "\n"
}
Source: /stylesheets/css3buttons/reset.css?1304745651 request.media_type: request.format: text/html Source: /stylesheets/css3buttons/css3-github-buttons.css?1304745651 request.media_type: request.format: text/html Source: /stylesheets/application.css?1304780110 request.media_type: request.format: text/html Source: /stylesheets/button-basics.css?1303711277 request.media_type: request.format: text/html Source: /stylesheets/global.css?1304739877 request.media_type: request.format: text/html Source: /javascripts/jquery.js?1302484024 request.media_type: request.format: text/html Source: /javascripts/rails.js?1302488107 request.media_type: request.format: text/html Source: /javascripts/jquery.maskedinput.js?1302484474 request.media_type: request.format: text/html Source: /javascripts/application.js?1300318225 request.media_type: request.format: text/html Source: /javascripts/jquery.js?1302484024 request.media_type: request.format: text/html Source: /javascripts/rails.js?1302488107 request.media_type: request.format: text/html Source: /javascripts/formToWizard.js?1256698412 request.media_type: request.format: text/html Source: /javascripts/application.js?1300318225 request.media_type: request.format: text/html Source: /javascripts/jquery.js?1302484024 request.media_type: request.format: text/html Source: /javascripts/rails.js?1302488107 request.media_type: request.format: text/html Source: /javascripts/rails_validations.js request.media_type: request.format: text/html Source: /javascripts/application.js?1300318225 request.media_type: request.format: text/html
Started GET "/medicalhistories/9.pdf" for 127.0.0.1 at Sun May 08 17:00:15 -0400 2011
code that generates the link to the pdf in my index.html.erb is below:
<td><%= link_to "PDF", medicalhistory_path(medicalhistory, :format => "pdf")%></td>
your problem is the snippet "source.format". In the proc passed to config.action_controller.asset_host, source is a string, and the format method is not going to be what you expect. I can think of two solutions to this problem.
Soltuon #1: test that the source strong ends with "pdf". Replace your second line with this:
source.ends_with?(".pdf")
Solution #2 - request.media_type
some people may consider solution #1 a little hacky... in which case they might be happier dealing with the request object instead. The request.media_type may contain the text/pdf mime type of the request. Im not positive of that though - if you go that route you should test it out first.
Looks like rails' routes are catching your requests and handing them off to action_controller. Here's 3 plans of attack:
1) If you have control over your httpd server, then you can probably alter its rewrite conditions if all the routing info is in the url.
2a) Otherwise, you can either alter rails' routes so that there is a specific action that handles these requests, like:
#routes
match '/medicalhistories/:id.pdf' => 'medicalhistories#pdf', :as => 'pdf_medicalhistory'
#MedicalhistoriesController
def pdf
redirect_to "http://file_path"
end
2b) Or, if you have lots of Rails-level access restrictions that are already implemented in the #show method, it could be better to handle these responses with a respond_to{|act| act.pdf{||} } as described here: http://www.engineyard.com/blog/2010/render-options-in-rails-3/ (with a redirect_to).
3) If you'd like, you could probably use a rack of middleware handler for this purpose. (Which is basically what you're implementing as your asset_host proc, so it shouldn't be too hard.)
Here's how they're building the middleware that does the rails config.serve_static_assets = true (open 'show source' on #call) and here's what installing it as middleware looks like.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With