How do I ignore a route in rails? - ruby-on-rails

I have a route i.e. mysite.com:3000/new_route that I'd like to ignore, is this possible to do through rails and not server side?
I've read that this can be done through apache, however, my app is running on Heroku and that type of control isn't accessible to me. Therefore, I'm looking for another way to do this through Rails.
Thanks
update
I am using faye to have live notifications in my app, on localhost faye runs on port 9292 - localhost:9292/faye, all good in development mode, but in production it should point to mydomain.com/faye, there are no port numbers in production environment, and loading faye.js returns error not found

If you're talking about a resources route you don't want to be created:
resources :something, except: :new
However, I'm not exactly sure if this is what you meant by ignore.

You can define a route at the top of your routes.rb file that will redirect to some other page.
get '/new_route', redirect: '/'

By the time you ask Rails to process the route, it is already too late. If you ask rails to process a route, it will, either by returning a 404 of 500 error, or a page.
If you want the route to be processed by another application, it will need to be intercepted by your webserver (nginx or apache, or whichever one you're using). In their configuration, you just redirect that route to the other application, and every other route to the Rails app.
EDIT
Another option you have, is to forward your requests to a different server.
You add a route like
get 'faye/*query' => 'faye#get'
post 'faye/*params' => 'faye#post'
And then a controller
require 'faraday'
class FayeController < ApplicationController
APP = 'http://mydomain.com:9292'
def get
request_page :get
end
def post
request_page :post
end
private
def request_page(method)
conn = Faraday.new(:url => APP)
query = params.delete(:query)
response = conn.send method, query, params
render text: response.body.gsub(APP, 'mydomain.com/faye')
end
end
which will use Faraday to load the information from your other application.

Related

Accessing request context object in rails router

I need to create a few dynamic routes in my rails router in the following way:
Rails.application.routes.draw do
account = Account.find_by(
subdomain: request.subdomain,
domain: request.domain
)
EditableField.where(account_id: account.id).links.each do |link|
get link.link_href, to: link.method
end
end
As shown above, I need to determine the account based on the request domain and subdomain, however I cant find how to access the request object in the rails router. What is the correct way to do this ?
I would suggest using the rack-rewrite gem
https://github.com/jtrupiano/rack-rewrite
It is in lower level and give you much more options to do this kind of dynamic routing
And if you still want to do that in the routes.rb file, you can follow this answer https://stackoverflow.com/a/24411835/2529330
Enjoy :)

Redirect all incoming domain variations to an absolute domain Heroku Rails

My setup is:
- Heroku
- Rails 3
- GoDaddy DNS
I'm trying to redirect all incoming routes of a domain variation to an absolute path. Including HTTPS.
For example:
algrim.co
www.algrim.co
http://www.algrim.co
http://algrim.co
Should all redirect to:
https://www.algrim.co
Heroku wants the application to do this. All I've tried within the application controller is this
before_filter :correct_domain!
def correct_domain!
if request.host == "https://algrim.co"
redirect_to "https://www.algrim.co#{request.fullpath}", :status => 301
end
end
But it doesn't cover all of the cases. Can someone help me here. How do I ensure all links pointing to my site are going to the correct places.

User based custom subdomains

I've tried to research and figure out how people are doing this without much success.
For my rails project I have projects that each have their own slug. The user can themselves dictate the slug and that slug will be the subdomain.
Now I'm trying to figure out how to do this routing wise and make it work in production as-well.
I have this now:
get '/', to: 'posts#index', constraints: { subdomain: /.+/, via: [:get] }, as: :feed
At a controller level I do:
before_action :get_project, only: :index
...
def get_project
unless #project ||= Project.find_by_slug(request.subdomain)
redirect_to root_url
end
end
When I test this on localhost using lvh.me it works. However when I try to do this on a live production server and check server logs, Rails return this:
ActionController::RoutingError (No route matches [OPTIONS] "/"):
Does anybody have any experience with this?
As for why your current code doesn't work in production you'd need to give us your web server's configuration if we are to help you debug it since that is probably the main difference between the two environments. Especially if your app is served behind a reverse proxy. But you may be able to solve this using this gem. Their implementation of this covers several cases and simplifies what your trying to achieve and may end up working in production. It allows mapping of subdomain routes in several ways that really saves a lot of time. What you might be really interested in is this section that talks about mapping routes with active record.

Rails is not routing to my Twilio controller action

I have a paid account with Twilio. In my rails app I have a very simple setup to answer an incoming phone call in rails with twilio. In routes.rb, I have
post 'communications/answer_phone' => 'communications#answer_phone'
In communications_controller.rb, I have
class CommunicationsController < ApplicationController
skip_before_action :verify_authenticity_token
def answer_phone
logger.debug '******** answered'
response = Twilio::TwiML::Response.new do |r|
r.Say "Yay! You’re on Rails!", voice: "alice"
end
render :xml => response.to_xml
end
end
If I try to call my Twilio number, ngrok says 500 Internal Server Error, so I know the request is getting to ngrok. If I look at my rails log file, I see
Started POST "/communications/answer_phone" for xxx.xxx.xxx.xxx at 2017-02-02 21:47:06 +1100
so, the request is making it to my application. I don't get ******** answered in my log file from logger.debug. The request never makes it to my answer_phone action. Any ideas what could be wrong?
UPDATE
I've done rake routes and that gives me
communications_receive_sms POST /communications/answer_phone(.:format) communications#answer_phone
That looks correct. If I deliberately spell the route incorrectly in routes.rb, I get this error
ActionController::RoutingError (No route matches [POST] "/communications/answer_phone"):
So I know the request is getting to my rails application and I know it is finding the route. What could cause rails to find the appropriate route but fail the call the associated action.
I've found a bug in rails 4.18. There is an example on the internet that makes it happen. See the link below
https://www.twilio.com/blog/2016/05/calling-rails-5-getting-started-with-twilio-on-rails.html
The example is for rails 5, so the bug must be fixed now. The following code line causes the error.
r.Say "Yay! You’re on Rails!", voice: "alice"
The apostrophe in "Yay! You’re on Rails!" is not the standard one on my computer keyboard. The normal apostrophe is hex character 0x27, the one in the word You’re is hex character 0x92. This causes a parsing error in rails. Even if I route to a different action in that controller, the error still occurs.
I hope this helps someone in the future.
EDIT
If you change the apostrophe, you'll have to restart your rails server to correct the problem

How do I prevent unwanted routing errors in production

ActionController::RoutingError (No route matches [GET] "/google83362a7a0f381ff0.html"):
I see the above logs in production, how should I prevent it.
If user mistypes a URL, how should I re-direct to a common error page
You can redirect the user to the desire page you want if no route matchs
Write down the following code at the bottom of your routes.rb file
In /config/routes.rb
#If no route matches
match ":url" => "application#redirect_user", :constraints => { :url => /.*/ }
Then redirect the user to the error page in the application_controller.rb file
*In /app/controllers/application_controller.rb*
def redirect_user
redirect_to '/404'
end
You don't need to trigger a controller to do that.
Just add this as the last rule in routes.rb:
match '*path', via: :all, to: redirect('/404')
Rails does this automatically when application running in production mode.When uploading application to live server, Rails takes care of handling those exceptions and rendering the correct error pages with the correct header status.You can directly find the files inside public folder.
Whenever you set up your Rails application on a live server, you give the site root as the /public folder in your application. Then, whenever a request is made to that server address, Web server first looks in that public folder and tries to serve a static asset (this is a configurable option in config/environment.rb). If it can't find the requested page, then the request is forwarded through the Ruby stack.
When in production mode, if Rails encounters an error that isn't handled, it throws the error to the stack, which then tells Web server to render an appropriate error.
Here are some common errors that you'll see in development mode and what they render in production mode:
ActiveRecord::RecordNotFound => 404 (page not found)
nil.method => 500 (server error) unless you turn off whiny nils
ActionController::RoutingError => 404 (page not found)

Resources