I'm fairly new to Rails, and my problem is as follows:
I'm making a GET request to a remote website via my server and I dish up the response as HTML to my front-end.
Unfortunately, the HTML I'm parsing from the remote site has references to static files which is causing a ActionController::RoutingError (No route matches [GET] "...")
How can I suppress these errors in my controller so that they don't appear in my browser console?
Code is as follows:
def get_page
url = URI.parse('[website]')
req = Net::HTTP::Get.new(url.path)
res = Net::HTTP.start(url.host, url.port) {|http|
http.request(req)
}
#result = res.body
respond_to do |format|
format.html { render :text => #result }
end
end
Appreciate any help!
I've figured this out, but I'm not sure if it's a very elegant solution.
In my routes.rb I put the following line at the bottom of all defined routes:
get '*static' => 'home#static_404'
I then put the following method in my "home controller":
def static_404
render :nothing => true
end
Seems to work, but I don't like how Rails forces me to use *[random_letters] to define this error route. * doesn't seem to work by itself, but if I type in anything afterwards it does.
Related
I got a ServiceWorker made with a webpack plugin that is public available with http://example.com/packs/sw.js URL. Since I want this Service Worker to control the whole website I need to serve it from http://example.com/. So, no redirect_to allowed
How do I have to set the routes.rb for this?
What I've tried is:
Added : get '/sw' => 'sw#show' to routes.rb
Created controller sw_controller.rb:
require 'net/http'
class SwController < ActionController::Base
def show
respond_to do |format|
format.all {
uri = URI('http://example.com/packs/sw.js')
res = Net::HTTP.get(uri)
render inline: res
}
end
end
end
It's ugly I know but should work:
Visiting http://example.com/sw.js gives No route matches [GET] "/sw.js"
Visiting http://example.com/packs/sw.js prints out the service worker correctly
Visiting http://example.com/sw prints out the service worker correctly
Also visiting http://example.com/sw.lol print the serviceworker
In config/initializers/mime_types.rb try adding:
Mime::Type.register "text/javascript", :js
This should allow format.all to recognise the Javascript request, which it will otherwise ignore.
Source: http://api.rubyonrails.org/classes/ActionController/MimeResponds.html
I have implemented an AJAX call that renders a JSON response.After checking my Firebug Console, I can see that the call results in a 404 Not Found error.
In my Controller (test_rules_controller.rb)
def rule_attributes
#test = RuleModel.find(params[:rule_model_id]).rule_attributes
respond_to do |format|
format.json { render :json => #test }
end
end
In my Routes:
get "/rule_models/:rule_model_id:/rule_attributes" => "test_rules#rule_attributes", :as => "rule_attributes", :format => :json
I have also created a rule_attributes.json.jbuilder file in my test_rules view folder:
json.rule_attributes #test
I am not sure why it is resulting in this error as I've never used JSON with routes before (Rails Newbie). When I try to navigate to the same URL in the browser, it raises the error that no route matches the given route (http://localhost:3000/rule_models/1/rule_attributes.json).
Can anybody please help?
Using Ruby 1.8.7 and Rails 3.2.12.
I am experiencing an issue when testing URLs with a ".json" extension. I'm building custom error pages and have the following:
# errors_controller.rb
def show
#exception = env["action_dispatch.exception"]
respond_to do |format|
format.json { render :json => { :error => #exception.message, :status => request.path[1..-1] } }
format.html { render :file => File.join(Rails.root, 'public', request.path[1..-1]), :format => [:html], :status => request.path[1..-1], :layout => false }
end
end
# routes.rb
match ":status" => "errors#show", :constraints => { :status => /\d{3}/ }
# application.rb
config.exceptions_app = self.routes
For URLs such as "localhost:3000/session/nourl.json", I trigger the HTML block of respond_to, and I can verify that the server responds with the HTML format with these logs:
Processing by ErrorsController#show as HTML
Parameters: {"status"=>"404"}
Rendered public/404.html (13.2ms)
Completed 404 Not Found in 48ms (Views: 47.3ms | ActiveRecord: 0.0ms)
The only way I've been able to trigger the JSON block is with :format => :json in the route, then it works fine but "localhost:3000/session/nourl" would respond with JSON too.
It feels like I am doing something foolish here because I've seen other examples of both cases being triggered in the expected way and I see absolutely no other cases of similar behavior, so I'm compelled to think this is an isolated situation or it's some cascading issue that I cannot observe or am causing elsewhere.
If anyone could provide some insight on potential issues I would be appreciative.
Updated:
A little more info: If I query something like "localhost:3000/locations/1.json", I get the expected response; a JSON formatted page with the object details. I can't achieve this same behavior when requesting arbitrary URLs with a ".json" extension and attempting to format a custom JSON response to return. Is there a way to do this?
Rails delegates the call to the Error-Application where all the request-format stuff gets lost. So you will need to check that on your own. You could check on the request information like this:
def api_request?
env['ORIGINAL_FULLPATH'] =~ /^\/api/
end
def json_request?
env['ORIGINAL_FULLPATH'] =~ /\.json$/
end
Read more about this approach here: http://phillipridlen.com/notes/2012/12/13/returning-multiple-formats-with-custom-dynamic-error-pages-in-rails/
I'm trying to get a rails app running with the node.js framework batman.js via the batman-rails gem.
When I'm responding with json in my rails controller, I get a 406 error everytime, and I don't know why. Here's my controller:
respond_to :json
def index
respond_with Sample.all
end
This gives me a 406 no matter what. I do not think this is related to batman, but rails itself. But for good measure, here's my batman code:
index: (params) ->
TopNavTemplate.Sample.load (err) -> throw err if err
#set 'samples', TopNavTemplate.Sample.get('all')
And then my index.html.erb file simply says 'index', it isn't really doing anything with batman yet.
There is a lot of 406 JSON related questions, I haven't really been able to apply them yet to my situation. Is there something I'm doing wrong to make rails respond_with JSON?
Alright, I made a very simple app to check out your situation:
SamplesController.rb
class SamplesController < ApplicationController
respond_to :json
def show
respond_with Sample.find(params[:id])
end
def index
respond_with Sample.all
end
end
When I visited /samples.json and samples/1.json, it worked as intended. However, when I went to /samples and /samples/1 (no .json extension), I got a 406 error.
In order to have the URL's work without the .json extension, you need to modify your config/routes.rb file as follows:
resources :samples, defaults: {format: :json}
Otherwise, the Rails application will attempt to respond to the request with an HTML response.
I am overriding Devise's failure response so that I can set a 401 status code. However, when the user fails to sign in, they are redirected to a page with a "you are being redirected" link. If I remove this :status => 401 from the redirect it works fine.
class CustomFailure < Devise::FailureApp
def redirect_url
new_user_session_url(:subdomain => 'secure')
end
def respond
if http_auth?
http_auth
else
store_location!
flash[:alert] = i18n_message unless flash[:notice]
redirect_to redirect_url, :status => 401
end
end
end
edit
Alternatively I would like to display the flash message and remain on the same page but adding this line of code:
render :text => "unauthorized", :status => 401
causes ruby to complain:
undefined method `render' for #<CustomFailure:0x00000103367f28>
What's happening here?
Proper HTTP statuses for a redirection are in the 30x form (301 and 302 being the most frequently used). By default, the redirect_to helper sets a 302 status header on the HTTP response. If you override that and set that to a 401, your web browser will assume that the response is a regular web page and will render the response body --which, in a redirection, is the boilerplate text "You are being redirected".
As said by #pantulis the browser will display this standard message if the response code is not a 3xx
To workaround this you can perform a javascript redirect:
# example with status 500:
render text: "<script>window.location = '#{url}';</script>", status: 500
This is off-course valid only if you are sure that all your users are using javascript. If your application can be browsed by users that may have disabled javascript you should also include a noscript tag and fallback in the standard "You are being redirected" message
I was actually running into this problem on our QA server, but not locally. It turned out that our memcache was intercepting the message and rendering it as a 200, and causing this message to appear. This was due indirectly to our memcache settings which didn't expect a re-direct from a GET.
From:
$document_root/cache/$uri.html /cache/$uri /cache/$uri.html $uri #memcached
To:
$document_root/cache/$uri.html /cache/$uri /cache/$uri.html $uri #rails
When I have this problem what I have done in the past is something like this:
#app/controllers/application_controller.rb
class ApplicationController < ActionController::Base
after_filter :check_page_content
...
private
def check_page_content
if response.body.include? "You are being"
html_doc = Nokogiri::HTML(response.body)
uri = html_doc.css('a').map { |link| link['href'] }.first
response.body = "<script>
window.location.replace('#{uri}');
</script>"
end
end
end
What I am doing is checking to see if the page content is "You are being". if this is true I know I am not where I want to be. and I just update the page to where I really want to be with some help of Javascript.
I know its not the most elegant solution but it really does help
Happy Hacking