Ruby - A request route with a wildcard doesn't work - ruby-on-rails

Could someone suggest why these 2 routes aren't the same:
get('/:id/' => 'outlets/play#show', :as => :listen, constraints: { id: /thetrack-a123-bay7623/ } )
get('/:id/' => 'outlets/play#show', :as => :listen, constraints: { id: /thetrack-.*/ } )
What I'm trying to achieve is only want that route outlets/play#show to be used when there is an :id that begins with thetrack.
I've found that if I explicitly use those characters its fine i.e. without thetrack in the route it doesnt use that route. However if I use thetrack-.* it still goes into the outlets/play#show route despite thetrack not being present in my request.
Any ideas?
I've tried other regex patterns e.g.
thetrack-.+
thetrack-.+-.+
thetrack-.*-.*
with no luck

If what you are trying to do is route any request /:id/ with ID starting with thetrack- to outlets/play#show, then your configured route should work:
get '/:id/', to: 'outlets/play#show', as: :listen, constraints: { id: /thetrack-.*/ }
Here are some example paths that will route to outlets/play#show using this wildcard:
/thetrack-
/thetrack-a123
/thetrack-a123-bay7623
/:id/ is quite broad reaching. Check that you have not got any other conflicting routes. i.e. another route at root level /:something/ that could be catching the other requests where thetrack- is not specified.

Related

Rails routing send string with dots and int

I'm new to rails...
I try to send such string as :search param: "55.675155, 21.833466" and 2 as :id param...
But something is bad...
i get No route matches [GET] "/exchanger_lists/get_exchangers_via_coordinates/.....
My route file:
match 'exchanger_lists/get_exchangers_via_coordinates/:search,:id' => 'exchanger_lists#get_exchangers_via_coordinates'
But also how then url must look in browser???
How to do this in Rails way? I read doc's, but something is not clear on 100% (
Just how to configure my route and how to call from browser?
match 'exchanger_lists/get_exchangers_via_coordinates/:search,:id' => 'exchanger_lists#get_exchangers_via_coordinates',
constraints: { search: /[^\/]+/ }
From here
You could change your routes like following:
match 'exchanger_lists/get_exchangers_via_coordinates/:x/:y/:id' => 'exchanger_lists#get_exchangers_via_coordinates'
params[:x] and params[:y] will hold your coordinates. I think this is more beautiful code, than holding the to coordinates in one param.

How to create rails route with constrants for numbers-only that accepts empty parameter?

I have created some route like this:
get 'foo/:offset' => 'foo#action', :as => :foo, :constraint => { id: /\d+/ }
It works fine, but: I want rails to route /foo to foo#action if no parameter specified, so not only urls like /foo/123 will be routed but simple /foo too.
How can I change constraint for this? Thanks for help!
I don't know if this is the best solution, but it's a simple one:
Create a route for /foo, and another for /foo/:offset to the same controller and action!

Dynamic Routing not rendering

So, I have a named route:
match 'ip/get/:ip' => 'ip_addresses#show', :via => :get
As you can see, I'd like the ip (after 'get') to be dynamic, but I keep getting a routing error when I try it out. Here are my routes:
root / ip_addresses#index
ip_add POST /ip/add(.:format) ip_addresses#create
GET /ip/add(.:format) ip_addresses#new
ip_all GET /ip/all(.:format) ip_addresses#index
GET /ip/get/:ip(.:format) ip_addresses#show
DELETE /ip/all(.:format) ip_addresses#destroy
And here's my show action:
def show
IpAddress.find(params[:id])
end
EDIT: Routing error:
ActionController::RoutingError (No route matches [GET] "/ip/get/1.2.3.4"):
I've read the Rails Routing from the Outside In Guide (http://guides.rubyonrails.org/routing.html) but naturally I may be overlooking something. Any help is appreciated. Thanks!
The answer to your question lays in article you gave.
Take a look at section:
By default dynamic segments don’t accept dots – this is because the
dot is used as a separator for formatted routes. If you need to use a
dot within a dynamic segment add a constraint which overrides this –
for example :id => /[^/]+/ allows anything except a slash.
Look at the example there:
match ':controller(/:action(/:id))', :controller => /admin\/[^\/]+/
So in your example I believe it would be:
match 'ip/get/:ip' => 'ip_addresses#show', :id => /[^/]+/ , :via => :get
And also change params[:id] to params[:ip]

Rails routes match starting with a numeric character

I have a an url like "http://domain.com/1and2" that I wanted to set up in config/routes.rb like this:
match "1and2" => "frontpage#oneandtwo"
(with controllers and views in place).
Running 'rake routes' outputs 'Invalid route name: '1and2''. This error is apparently triggered when you start a match with a numeric character.
Is there a workaround, or am I doing it wrong?
match '/:id' => "frontpage#oneandtwo", :constraints => {:id => /1and2/}
The root of the problem is that methods in Ruby cannot start with a number. Since Rails routing will generate an accessor method for each route, you'll get an error.
You can pass by the issue by naming your route differently with the :as parameter.
I had an issue where I wanted to redirect from a URI /2012 -- which resulted in an error. I corrected it by adding :as => current_year to the routing:
match "/#{Time.now.year}" => redirect("..."), :as => :current_year
Further information:
https://github.com/rails/rails/issues/3224

ROR route with parentheses in constraint

I'm trying to create a rails route for movies (on the root path) that has parentheses containing the movie's year in it.
E.g. Men in black => "/men-in-black-(1997)"
My route is:
resources :movies,
path:'/',
only:[ :index, :list, :show ],
constraints: { id: /[A-Za-z0-9-]+\(\d{4}\)/ }
When I use this route (movie_path(Movie.first)), I get
"ActionController::RoutingError: No route matches: ..."
When I change the route constraint to:
constraints: { id: /[A-Za-z0-9-]+\\\(\d{4}\\\)/ }
the route works when using the url routing helper. However, the route doesn't work for the reverse mapping (e.g. taking "/men-in-black-(1997)" and routing it to the correct action/controller). When I run (from console):
Rails.application.routes.recognize_path("/men-in-black-(1997)")
I get the same routing error:
ActionController::RoutingError: No route matches
The problem seems to be associated to how rails escapes regex's in routing. For escaping with \( the object-to-route map fails, but url-to-route works. But when escaping with \\\( it is the opposite.
Anyone have any tips or experience with this?
As a workaround hack you could try:
constraints: { id: /[A-Za-z0-9-]+(\\\(\d{4}\\\)|\(\d{4}\))/ }
That is, make the constraint accept either, if it accepts one in one case and the other in the other case.
Which is to say: that's weird, I have no idea why Rails would do that or how to fix it ;)
Well I don't have a lot of experience writing regex constraints, but you could always do a wildcard route and then sanitize in the controller.
match 'movies/*movie' => 'movie#action'
This will give you access to a :movie param with all the characters input

Resources