How can I create a Rails 3 route that will match all requests and direct to one resource / page? - ruby

I have a rails app (Rails 3.0) that I need to temporarily take out of service. While this is in effect, I want to create a new route that will direct all requests to a single piece of static content. I have a controller set up to serve my static pages.
I tried something like this:
match '*' => 'content#holding'
and
match '*/*' => 'content#holding'
to match a wildcard route as described here:Rails 3 route globbing without success.
This is probably a really simple answer, but I couldn't figure it out.
/EDIT/
Forgot to mention that I did have this rule at the very top of my routes.rb file.

Rails needs to bind the url parameters to a variable, try this:
match '*foo' => 'content#holding'
If you also want to match /, use parenthesis to specify that foo is optional:
match '(*foo)' => 'content#holding'

I did this just yesterday and first came up with the solution that klochner shows.
What I didn't like about this is the fact that whatever you enter in the URL, stays there after the page loads, and since I wanted a catch all route that redirects to my root_url, that wasn't very appealing.
What I came up with looks like this:
# in routes.rb
get '*ignore_me' => 'site#unknown_url'
# in SiteController
def unknown_url
redirect_to root_url
end
Remember to stick the routes entry at the very bottom of the file!
EDIT:
As Nick pointed out, you can also do the redirect directly in the routes file.

I ran into something like this where I had domain names as a parameter in my route:
match '/:domain_name/', :to => 'sitedetails#index', :domain_name => /.*/, :as =>'sitedetails'
The key piece to this was the /.*/ which was a wildcard for pretty much anything. So maybe you could do something like:
match '/:path/', :to => 'content#holding', :path=> /.*/, :as =>'whatever_you_want'

Where in "routes.rb" is this line located?
To have priority over other routes, it has to be placed first.
As an alternative, you can look into this: http://onehub.com/blog/posts/rails-maintenance-pages-done-right/
Or this: Rails: admin-only maintenance mode

Related

Rails 4 custom path helper

I would like to customize my path helpers in Rails 4.
I have a Site5 website (which uses Apache server) with multiple subdomains. I have rewrite rules in my .htaccess file which adds the folder name to the url. For example
cs1337.mysite.com/login
is rewritten to
cs1337.mysite.com/cs1337/login
In routes.rb, I have added a scope in routes.rb:
scope '/cs1337' do
get '/login', to: 'sessions#new', as: :login
# etc.
end
which gives me the correct routing. Everything works, but the annoying thing is that all my path helpers have the '/cs1337' prefix, which is unnecessary since the .htaccess rewrite rules add it back in. For example,
login_path # => /cs1337/login
when only
login_path # => /login
is necessary.
I would like to override all of the path helpers to strip off the prefix, using something like
def <override all path helpers>
path = super
path.gsub(%r{^/cs1337}, '')
end
I know the path helpers are dynamically generated, but I can't figure out where start ... I can't even find what module the path helpers are generated in.
Thanks for any help you can offer!
Short answer: No, as far as I can tell.
I couldn't find anything that lets you have the route Rails intercepts be different from the path that the helpers give you. I don't think Rails plays well with .htaccess rewrites.
Do you need the folder name to be in the path? If not, I would remove the scope '/cs1337' do and use something like this StackOverflow post to do domain-specific routes.
If you need it there, I would recommend being okay with the end user seeing "cs1337.mysite.com/cs1337/path".

URL Rewrite Ruby on Rails

We have a Redmine installation on an old server and moved it to a new one with a new domain. Problem is, we need to redirect urls from the old domain to the new one. I really don't have much knowledge about ruby. I was thinking redirecting URLs on this one is as easy as some rewrite rules with .htaccess but I found it different. I've read some answers here redirect but can't figure out where to put those codes.
The scenario should be like:
from http://www.old-domain.com:3000/issues/3456
should be redirected to http://www.new-domain.com:3000/issues/3456
Can anyone help me how to do this? Or if you have better idea how to achieve this?
I'm planning on reading some ruby guides for the meantime.
Thanks guys!
Update:
I managed to create a simple redirect by doing the following:
I created a controller redirect_controller.rb:
class RedirectController < ApplicationController
before_filter :show
def show
redirect_to "http://www.new-domain.com:3000/", :status => :moved_permanently, :notice => "Notice: A redirect!!!"
end
end
And added this to routes.rb:
map.connect '/', :controller => 'redirect'
But I only managed to redirect the page after a successful login. How can I redirect all pages to the new one retaining parameters such as /issues/3456 if there are any?
You can go to your application.rb file (I found it better than place the redirection in the application controller), which is loaded to start all the rails and all engines. The key here is to use
head :moved_permanently, :location => "http://www.newdomain.com/"
To call that you can wrap it in a method I found in a blog. I added some comment
def perm_redirect_to(options)
url = case options
when String # if you pass a string url, which is your case
options
else
url_for(options) # if you pass some more complex option hash in
# `options`, which doesn't seem to be your case
end
head :moved_permanently, :location => url
end
You can call this method passing your url perm_redirect_to(your_new_url)!

Global before filter in padrino - how is it done?

The padrino docs let you know how to do a before filter in the context of a controller, but I'm trying to do a global filter.
The problem I'm trying to solve is that my domain name should be forwarded to the www. version, but godaddy isn't doing it properly. So now I want to manually redirect in my code - and hence the global before filter.
Or should I be looking at 'middleware' instead?
Try to use rack-rewrite gem
In your config.ru add something like
require 'rack/rewrite'
use Rack::Rewrite do
r301 %r{.*}, 'http://www.your-domain.com$&',
:if => Proc.new { |rack_env| rack_env['SERVER_NAME'] != 'www.your-domain.com' }
end
Dont forget to include gem 'rack-rewrite' into your Gemfile.
First result in google http://logbook.route19.com/post/9018495987/sinatra-redirect-www-to-non-www
Just make the opposite of that link. Try something like that :
before do
redirect "www.#{request.url}" unless request.host =~ /^www/
end
I've added my global before filters to app.rb. Not sure if this is the correct way, but it works just the same as adding the before filter in my controller.
In your app.rb file
before do
# Code goes here
end

Trouble creating custom routes in Ruby on Rails 3.1

I can't seem to set up a custom URL. All the RESTful routes work fine, but I can't figure out how to simply add /:unique_url to the existing routes, which I create in the model (a simple 4 character random string) and will serve as the "permalink" of sorts.
Routes.rb
resources :treks
match ':unique_url' => 'treks#mobile'
Controller
.
.
def mobile
#trek = trek.find(params[:id])
end
Is this because I'm trying to define a custom action on an existing resource? Can I not create custom methods on the same controller as one with a resource?
By the way, when I change routes.rb to match 'treks/:id/:unique_url' => treks#mobile it works fine, but I just want the url to simply be /:unique_url
Update It seems like find_by_[parameter] is the way to go...
I've been playing in console and I can't seem to get any methods to come forward...I can run Trek.last.fullname for example, but cannot run #trek = Trek.last...and then call...#trek.lastname for example. Any clues why? I think this is my issue.
So is there a field on Trek which stores its unique url? If so you should be doing something like this:
#trek = Trek.find_by_url(params[:unique_url])
trek.find_by_unique_url( params[:unique_url] ) # should do the trick
#pruett no, the find_by_XXX methods are generated on-the-fly via Ruby's method_missing call! So instead of XXX you can use any of the attributes which you defined in a model.
You can even go as far as listing multiple attributes, such as:
find_by_name_and_unique_url( the_name, the_unigue_url)
Check these pages:
http://guides.rubyonrails.org/active_record_querying.html
http://m.onkey.org/active-record-query-interface
if you get a undefined method ... for nil:NilClass , it means that the object you are trying to call that method on does not exist, e.g. is nil.
You probably just missed to put an if-statement before that line to make sure the object is non-nil
Hmm. I usually would do something like this:
map.connect "/:unique_url", :controller => "treks", :action => "mobile"
Then in that controller the ID isn't going to be applicable.. you'd need to change it to something like this:
def mobile
#trek = trek.find_by_unique_url(params[:unique_url])
end
(that's if unique_url is the column to search under)

Rails redirecting invalid route to root

If my website is www.foo.com if the user types www.foo.com/blahblahblah it will say that /blahblahblah is an invalid path (obviously). But I want it instead to redirect to the root_path so that the controller can process the URL -- the page www.foo.com should be rendered I want to pull the text blahblahblah and do something with it. How do I do this?
There are several possibilities. Here's one. You could add this to the bottom of your routes.rb:
match ':not_found' => 'my_controller#index',
:constraints => { :not_found => /.*/ }
which will establish a catch-all route to make MyController's index action handle any missing paths; it can detect them by looking at params[:not_found] and doing whatever it wants, such as redirecting to the root_path (redirect_to root_url), redirecting somewhere strategically based on the bad path, rendering something special, examining the referrer/referer for clues about the source, etc.
The :constraints option is necessary; otherwise the not_found param won't be able to contain special characters like slashes and dots.
Put this at the bottom of your routes because, obviously, it will match everything, and you want to give your other routes first crack at the path.
If you only want to redirect, nothing more, you could do this instead (again, at the bottom):
match ':not_found' => redirect('/'), :constraints => { :not_found => /.*/ }
in rails 4
get '*path' => redirect('/')

Resources