How to have + in named routes in ruby on rails? - ruby-on-rails

I have a route in my routes.rb ie
match '/googleplus' => redirect("https://plus.google.com/+username"), :as => :googleplus
So in browser if someone open
www.example.com/googleplus
he will redirected to google plus page. Now I want to make it
www.example.com/google+
or
www.example.com/+google
to achieve the same thing. How can I do that?

You can't 'simply' do this, you must URL encode it but in this way this will not be accomplished anyway.
Explanation here

You can escape the + character. Your route would look like this.
match '/googleplus' => redirect("https://plus.google.com/\+username"), :as => :googleplus

You'll need to encode the '+', since that usually gets replaced with a space by most browsers. The URI encoding for '+' is '%2B':
match '/google%2B' => redirect("https://plus.google.com/+username"), :as => :googleplus
match '/%2Bgoogle' => redirect("https://plus.google.com/+username"), :as => :googleplus

Related

Error using wildcards and redirect on routes in Rails

match "/myroute*" => redirect("http://google.com"), :as => :myroute
The line above in routes.rb is causing the following error
/Users/user/.rvm/rubies/ruby-1.9.2-p290/lib/ruby/1.9.1/racc/parser.rb:349:in `on_error': (Racc::ParseError)
parse error on value ")" (RPAREN)
from /Users/user/.rvm/rubies/ruby-1.9.2-p290/lib/ruby/1.9.1/racc/parser.rb:99:in `_racc_do_parse_c'
from /Users/user/.rvm/rubies/ruby-1.9.2-p290/lib/ruby/1.9.1/racc/parser.rb:99:in `do_parse'
Looks like it is because I'm adding a wildcard (*). Any idea how to solve this?
Wildcard components need to have a "label" as well, e.g.
match "/myroute*something" => redirect("http://google.com"), :as => :myroute
will match /myrouteblah and /myroute/hello/world where params[:something] is blah and /hello/world respectively.
EDIT: Check out http://guides.rubyonrails.org/v3.2/routing.html#route-globbing if you haven't already.
Try this:
match ':redirect' => redirect("http://google.com"), :as => :myroute , :constraints => { :redirect => /myroute.?/i }

Route in rails with simple regex doesn't match

I looked on the web for a while but I can't get this to work. Our application has to work with urls like ourapp.com/meandyou, where the common element is the "and" in the parameter.
I saw that it's possible to constrain urls parameters using regex, so I added the rule to routes.rb, but without success. If I try to match the same expression using the terminal, it works. Here's the complete route file:
Railroot::Application.routes.draw do
resources :couples
get "home/index"
root :to => 'home#index'
match ':url' => 'couples#show_url', :url => /and/
end
I read that Rails nests the expression within a bigger one when matching the route, so maybe I'm doing something slightly wrong even for such a simple expression.
I'm running on Ubuntu 10.04, Ruby 1.9.3, Rails 3.2.3, Passenger 3.0.13, Nginx 1.2.1.
Thanks in advance for your help!
This should be your starting point:
Railroot::Application.routes.draw do
root :to => 'home#index'
resources :couples
match ':url' => 'couples#show_url', :constraints => { :url => /and/ }
end
This may be your answer, from the rails routing docs:
:constraints takes regular expressions with the restriction that regexp anchors can’t be used. [...]
However, note that you don’t need to use anchors because all routes are anchored at the start.
So I think what you are actually matching against is not /and/ but /^and/, which would explain why it's not working.
Try being more explicit, like this:
match ':url' => 'couples#show_url', :url => /.*and/

Routing more than one action to the same controller and action

I am trying to get something like this working on my Rails app:
match '/:language', :to => 'posts#search_result'
match '/:tag', :to => 'posts#search_result'
match '/:language/:tag', :to => 'posts#search_result'
I am using this search_result action to filter some posts depending of the language and the tag.
The problem is that sometimes :tag will be nil or :language will be nil; so i have these 3 possibilities when calling the action:
<%=link_to "Spanish", {:controller => 'posts', :action => 'search_result', :language => "spanish"} %>
<%= link_to "Spanish", {:controller => 'posts', :action => 'search_result', :language => "spanish", :tag => #tag} %>
<%=link_to "#{tag.name}", {:controller => 'posts', :action => 'search_result', :tag => #tag} %>
And I am expection to have URLs like:
/spanish (for the first case)
/spanish/rails (where rails is a tag, for the second case)
/rails (for the third case)
But right now i am getting the rigth thing for the first and third case, but for the second case i am getting:
/spanish?tag=rails
or again /spanish (depending on if i had selected a tag first or a language first).
I hope i explained myself right. Any idea??. thanks!.
The router cannot tell the difference between a :language and a :tag.
Just because your routes say "language" and "tag" when you are constructing your code in the view.. remember that in the html this has been translated into just plain ole URLs eg /spanish or /rails
the route then has to be figured out from this URL.
Now as I said, the router can't tell that a particular word is a language or a tag... and the plain-ole-URL doesn't have the word "tag" or "language" in it anymore... so your two routes here:
match '/:language', :to => 'posts#search_result'
match '/:tag', :to => 'posts#search_result'
are both the same kind of URL
Just a single token after the slash. Here are some examples that will match that route:
/greek
/spanish
/rails
/urdu
/whatever
They will all match the first route that matches on "a single token after a slash"... which means your router will match all of them to the "language" route and will never ever match the "/:tag" route, because it's already matched on the route above.
he he: it's all greek to the router ;)
Edit:
Hi, this is helping me a lot to understand how routing works.. but still i can't see it clear. I understand what you said, and so basically i understand i should do something like match '/tags/:tag to at least only route to posts#search_result the URLS starting by /tag .. what would be a solution??
yes, "/tags/:tag" would be clear and unambiguous, but if you want it to truly flexible in tag vs language you would be better served by the simple:
match '/posts/search', :to => 'posts#search_result'
which can use any of your link_to examples above to generate eg:
/posts/search?tag=rails
/posts/search?language=spanish
/posts/search?language=spanish&tag=rails
It's also far more clear what is being passed and why.
The description of the third URL is "I'm searching for a set of posts which have language = spanish and tag = rails"
Your URL should reflect the resource (which in this case is a set of posts) everything else is better done as query params.
Instead of defining /:language and /:language/:tag separately, define them together, with /:tag as an optional URI element.
match '/:language(/:tag)', :to => 'posts#search_result'
I believe routes are matched (and URIs generated from them) in the order that the routes are defined. You defined /:lang before you defined /:lang/:tag, so it matched /:lang and made :tag a GET parameter. I suppose you could optimize the ordering of your definitions, but I believe using the above syntax is the preferred method.

Handle rails route with GPS parameter

I'd like to create a route in my rails app to handle a gps-coordinate parameter. The intention is to find restaurants near the given position.
This is were I started:
match "/restaurants/near/:lat/:lng(/:range)", :to => "restaurants#near", :as => "near", :constraints => {:range => /\d+/}
It seems the router has problems with float parameters, an url like /restaurants/near/53.0123/10.5678 isn't recognized. Do you have a solution or best practice for handling GPS coordinates in rails urls?
Thank you!
The problem is caused because Rails try to use the "dots" for search for the format (.:format)
So, you can add some constraints to fix it, for example:
match "/restaurants/near/:lat/:lng(/:range)", :to => "restaurants#near", :as => "near", :constraints => {:lat => /\-?\d+(.\d+)?/, :lng => /\-?\d+(.\d+)?/ , :range => /\d+/}

rails routes problem

here are my routes.i want to prevent duplicate url
match ':id' => 'people#show'
match 'people/:id' => redirect("%{id}")
How about?
match '(people)/:id' => 'people#show'
Bound Parameters

Resources