Rails custom routes with params - ruby-on-rails

I am trying to display params in my url so i have added
patient_record_path(:limit => 10)
I am now trying to correctly route this.
Currently i am getting the error
No route matches {:action=>"show", :controller=>"patient_record", :limit=>10}
I am currently using the route
match 'patient_record/show&limit', :to => 'patient_record#show'

You should not add the limit to your route. Just simple define your route like this:
match 'patient_record/show', :to => 'patient_record#show', :as => 'patient_record_show'
A better solution however would be
resources :patient_records
This would create the following path helpers:
patient_records_path => "/patient_records" => 'patient_record#index'
new_patient_record_path => "/patient_records/new" => 'patient_record#new'
edit_patient_record_path(:id) => /patient_records/:id/edit => 'patient_record#edit'
patient_record_path(:id) => "/patient_records/:id" => 'patient_record#show'
Update: wrong use of path helper
I have looked at your question again and found another bug: the path helper for show needs a record. The correct use is:
# path to show
patient_record_path(#patient_record, :limit => 10)
# path to index
patient_records_path(:limit => 10)

Related

How to add alias in routes.rb

How to add alias to route file?
Something like this:
/rules => 'posts/1', param: id => 1
Is it possible define it in routes.rb
I want
/rules => posts/1
not
/rules/1 => posts/1
Well, let's look at the official Rails routing guide:
You can also define other defaults in a route by supplying a hash for the :defaults option. This even applies to parameters that you do not specify as dynamic segments.
So then:
get "/rules" => "posts#show", :defaults => { :id => "1" }
try this
get '/rules', to: redirect('/posts/1')
http://guides.rubyonrails.org/routing.html#redirection

Why rails is not generating a route helper for my 'match' route?

This is the two routes i declared in my config/routes.rb file :
namespace :projects do
match "proj_rapports_contributeur/select" => 'proj_rapports_contributeur#select', :via => :get
match "proj_rapports_contributeur/generate/:id" => 'proj_rapports_contributeur#generate', :via => :get
end
This is the resulting routes and helpers rails generate with rake routes :
projects_proj_rapports_contributeur_select_fr /hierarchie/rapports_contributeur/selectionner(.:format) projects/proj_rapports_contributeur#select {:locale=>"fr"}
projects_proj_rapports_contributeur_select_en /en/projects/proj_rapports_contributeur/select(.:format) projects/proj_rapports_contributeur#select {:locale=>"en"}
/hierarchie/rapports_contributeur/generer/:id(.:format) projects/proj_rapports_contributeur#generate {:locale=>"fr"}
/en/projects/proj_rapports_contributeur/generate/:id(.:format) projects/proj_rapports_contributeur#generate {:locale=>"en"}
I don't understand why rails didnt generate a route helper for the second route ?
Don't be surprised with the translated route. I'm using the gem 'rails-translate-routes' to translate routes (Resource : https://github.com/francesc/rails-translate-routes)
=== UPDATE for FINAL ANSWER ===
According to the answeer, for those wanting to know the end word, here it the routes I will be using :
namespace :projects do
get "proj_rapports_contributeur/select" => 'proj_rapports_contributeur#select'
get "proj_rapports_contributeur/generate/:id" => 'proj_rapports_contributeur#generate', :as => 'proj_rapports_contributeur_generate'
end
And these are the resulting helpers :
projects_proj_rapports_contributeur_select_fr GET /hierarchie/proj_rapports_contributeur/selectionner(.:format) projects/proj_rapports_contributeur#select {:locale=>"fr"}
projects_proj_rapports_contributeur_select_en GET /en/projects/proj_rapports_contributeur/select(.:format) projects/proj_rapports_contributeur#select {:locale=>"en"}
projects_proj_rapports_contributeur_generate_fr GET /hierarchie/proj_rapports_contributeur/generer/:id(.:format) projects/proj_rapports_contributeur#generate {:locale=>"fr"}
projects_proj_rapports_contributeur_generate_en GET /en/projects/proj_rapports_contributeur/generate/:id(.:format) projects/proj_rapports_contributeur#generate {:locale=>"en"}
This is because the route is not a simple route, it contains a parameter (in your case :id). In this case, you should specify the route name manually using as
match "proj_rapports_contributeur/generate/:id" => 'proj_rapports_contributeur#generate', :via => :get, :as => "your_route_name"
As a side note, replace match + via with the corresponding method name.
get "proj_rapports_contributeur/generate/:id" => 'proj_rapports_contributeur#generate'
It's shorter, and match is deprecated in Rails 4.

Rails url_for from string with parameters

I've got a site-local tinyurl I'm trying to make, so I need to show the full path of a URL that doesn't correspond to a controller action, and this doesn't work:
url_for("tiny/#{identifier}", :only_path => false)
because the url_for that takes a string doesn't then take any parameters.
How can I accomplish this?
Edit as per comment:
config/routes.rb:
get 'tiny/:id' => "original_controller#show", :constraints => {:id => /\d+/}
get 'tiny/:name' => "original_controller#by_name"
rake:
GET /tiny/:id(.:format) original_controller#show {:id=>/\d+/}
GET /tiny/:name(.:format) original_controller#by_name

How to match hash (deep nested) params in Rails3 to make a pretty URL?

If I have this route (in routes.rb):
match 'posts', :to => 'posts#index'
It will show and match the following routes:
# Case 1: non nested hash params
posts_path(:search => 'the', :category => 'old-school')
#=> "/posts?search=the&category=old-school"
# Case 2: nested hash params
posts_path(:filter => {:search => 'the', :category => 'old-school'})
#=> "/posts?filter[search]=the&filter[category]=old-school"
If I want to make the category param part of the main URL, I could do this for the Case 1.
match 'posts(/:category)', :to => 'posts#index'
that will show and match the following routes:
# Case 1: non nested hash params
posts_path(:search => 'the', :category => 'old-school')
#=> "/posts/old-school?search=the"
But how could I do the same if the param is nested (Case 2)?
I would expect the next route definition:
match 'posts(/:filter[category])', :to => 'posts#index'
to work this way:
# Case 2: nested hash params
posts_path(:filter => {:search => 'the', :category => 'old-school'})
#=> "/posts/old-school?filter[search]=the"
But it does not work.
I found this same question in two places with no righ answer:
how-to-specify-nested-parameters-in-the-routes
how-to-accept-hash-parameters-in-routes
The Rails Guides don't specify anthing about this.
Should I assume that this can not be done in rails? really?
you could just make two different routes instead
match 'posts', :to => 'posts#index'
match 'posts/:category', :to => 'posts#index'
The next route will not work as you intended it.
match 'posts(:filter[category])', :to => 'posts#index'
The :filter is just a place holder for either the first argument thats passed into the url helper or the value for the key :filter in a has that is passed in. Any expressions in the route string will not be evaluated.
I guess the answer to your question is that you cannot do this in rails. I would suggest to you though that you do this in another way. It is very helpful in rails to follow the convention and make things easier on yourself.
Looks like you are doing three things here. The base post routes
match 'posts', :to => 'posts#index'
A route that has the category nested in it. Most likely to give the user a better url
match 'posts/:category', :to => 'posts#index'
And a search url which can be the same as the first, or to make your action cleaner, a different one
match 'posts/search', :to => 'posts#search'
There is really no reason I can think of to complicate the routes in the way your are suggesting. A search query url doesn't look nice anyways so why bother handling two urls for searches. Just one will do.
You should definitely take a look at running
rake routes
as this will tell you exactly what you have defined in your routes file. You can also set up routing tests to ensure your custom routes are performing correctly.
Your example does not work (as you indicated)
# Case 2: nested hash params
posts_path(:filter => {:search => 'the', :category => 'old-school'})
#=> "/posts/old-school?filter[search]=the"
But what you should be looking for is this
posts_path(:filter => {:search => 'the', :category => 'old-school'})
#=> "/posts?filter[search]=the&filter[category]=old-school"
This is ok to do it this way.
If you want to keep posts/:category just use this for navigation only, not for search.
Hope that helps

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+/}

Resources