What is the difference between get and match in rails used for routing?
For example, using get, I can write
get '/users' "users#index", as => 'all_users'
And can't I do the same thing using match like the following:
match '/users' => 'users#index', as => 'all_users'
When I should choose one and why?
get, post and all other related methods are only helpers and they use match underneath. You can see the implementation here. Use match when you need to set the route for multiple verbs (see here).
get defines a route that allow request via the HTTP GET method. get is prefered if only want to respond to one method:
get 'users', to: 'users#index', as: 'all_users'
If you want to respond to multiple method you can use match, but should still define the allowed methods for security reasons:
match 'user', to: 'users#index', as: 'all_users', via: [:get, :post]
Quote from the Rails Docs:
You should not use the match method in your router without specifying an HTTP method.
Related
I need to match this link /links/128/dev?usrA=mike&usrB=carl with my controller.
I tried using:
match 'links/:id/dev?usrA=:curr&usrB=:prev', to: 'links#index', via: :get
But it does not work.
Is there any way to match this URL with my controller?
I generally avoid match and prefer the more explicit get (if you will only allow a GET)
get 'links/:id/dev', to: 'links#index'
You do not have to specify the parameters, these are parsed automatically.
match 'links/:id/dev', to: 'links#index', via: :get
You don't need to be explicit while sending a GET request. You can send whatever you want in the GET request, and can receive in the method through the params.
match '/links/:id/dev', to: 'links#index', via: :get
Will work fine. Everything after the "?" are considered parameters and are not considered when matching the URL.
match '/links/:id/dev' => 'controller#action', :via => [:get], :as => :get_links
Then you can access using get_links_path() from javascript
I would like to create nested routes for my forum, where a topic belongs to a category.
I'm not liking the default nested routes
resources :forum_category do
resources :forum_topic
end
which would give me something like /forum_category/[forum_category_id]/forum_topic/[forum_topic_id]
What I want:
I'm looking to create the following rules (leaving out POST, PATCH, PUT routes)
/forum => forum_topic#index
/forum/new => forum_topic#new
/forum/[forum_category_id] => forum_topic#index
/forum/[forum_category_id]/[forum_topic_id] => forum_topic#show
So /forum is my index, forum/open-mic is my index limited to category with seo slug open mic and finally /forum/open-mic/lets-talk-about-fun would be my forum topic lets-talk-about-fun which is categorized under open-mic.
Is there any solution for this build into Rails?
If you're just looking for GET requests you can do this:
get '/forum', to: "forum_topic#index", as: :forum_topics
get '/forum/new', to: "forum_topics#new", as: :new_forum_topic
get '/forum/:forum_category_id', to: "forum_topics#show", as: :forum_topic_category
get '/forum/:forum_category_id/:forum_topic_id', to: "forum_topic#show_topic", as: :show_forum_topic_category
You could map the last two to the same controller action and redirect based on params, but I'd recommend setting up two separate actions for readability.
you can do like this for customize routes:
match "<your-url>", to:"<controller>#<action>", as: "<path-name>", via: :<your method-like GET,POST,DELETE>
for example to GET:
match "forum_category/:forum_category_id/forum_topic/:forum_topic_id", to: "forum_topic#show", as: "show_topic", via: :get
and for POST:
match "forum_category/:forum_category_id/forum_topic", to: "forum_topic#update", as: "update_topic", via: :post
in your controller you have this params:
param[:forum_category_id] and param[:forum_topic_id]
In rails 3 match keyword is working but in rails 4 match keyword is not working for routes
how can i define these routes in rails 4
this code segment is working in rails 3
match 'admin', :to => 'access#menu'
match 'show/:id', :to => 'public#show'
match ':controller(/:action(/:id(.:format)))'
i need generic formula for rails 4 like in rails 3
match ':controller(/:action(/:id(.:format)))'
Rails 4 removed generic match, you now have to specify which verb you want it to respond to. Typically you'd define your routes as:
get ':controller(/:action(/:id(.:format)))' => 'foo#matcher'
If you want it to use match to get multiple verbs, you can do it like this:
match ':controller(/:action(/:id(.:format)))' => 'foo#matcher', via: [:get, :post]
What is said in documentation:
In general, you should use the get, post, put and delete methods to constrain a route to a particular verb. You can use the match method with the :via option to match multiple verbs at once:
match 'photos', to: 'photos#show', via: [:get, :post]
You can match all verbs to a particular route using via: :all:
match 'photos', to: 'photos#show', via: :all
(documentation)
the best way to do this is to first find the output of rake routes
$ rake routes
you'll get something like this:
[rails path] [verb] [url format] [controller#action]
so for example:
user_show GET /show/:id public#show
the action is what you need to look at. You should be using get or post rather than match - like this:
get 'show/:id', :to => 'public#show'
post ':controller(/:action(/:id(.:format)))'
I know rails uses the controller action style urls like www.myapp.com/home/index for example
I would like to have a url like this on my rails app, www.myapp.com/my_page_here is this possible and if so how would I go about this?
You just use a get outside of any resources or namespace block in your routes.rb file:
get 'my_page_here ', :to => 'home#index'
Assuming you are using Rails 3+, do NOT use match. It can be dangerous, because if a page accepts data from a form, it should take POST requests. match would allow GET requests on an action with side-effects - which is NOT good.
Always use get, put, post or these variants where possible.
To get a path helper, try:
get 'my_page_here ', :to => 'home#index', :as => :my_page
That way, in your views, my_page_path will equal http://{domain}/my_page_here
you just need to make a routing rule to match that url
in this case it will be something like
match 'my_page_here' => 'your_controller#your_action'
your controller and action will specify the behavior of that page
so you could do
match 'my_page_here' => 'home#index'
or
get 'my_page_here', :to => 'home#index'
as suggested in other responses.
for index action in home controller if you have such a controller
see http://guides.rubyonrails.org/routing.html for more details
also see Ruby on Rails Routes - difference between get and match
I have a Rails app that does everything I need it to do via a HTML interface, now I'd like to bolt on an API providing access to bits of the functionality.
How would I do this selective forwarding of some API controller actions to another controller's actions using the Routes.rb?
I have tried the following:
My regular controller routes work fine using:
match 'stuff' => 'stuff#index'
get 'stuff/index'
get 'stuff/some_get_action'
post 'stuff/some_post_action'
But then when I try for my API:
match 'api' => 'api#index'
match 'api/some_get_action' => 'stuff#some_get_action', :via => :get
match 'api/some_post_action' => 'stuff#some_post_action', :via => :post
or...
match 'api' => 'api#index'
get 'api/some_get_action', :to => 'stuff#some_get_action'
post 'api/some_post_action', :to => 'stuff#some_post_action'
I get an error. When I navigate to /api/index to server a HTML page that contains forms for testing the API URLs the url_for raises a 'Routing error' exception saying 'No route matches...'.
You may want to include ':as => ' and define your route names that you may be using as your link paths.
get 'api/some_get_action' => 'stuff#some_get_action', :as => 'some_get_action'
and the link path in your index file will have 'some_get_action_path'. Not sure that 'match' or 'get' automatically resolves to a path name, which by setting ':as' it definitely will.
I like your idea for setting up this page for testing. I'm always doing it in the console, which is surely more difficult than simply clicking a link. Your links probably need to infer that they are :json requests, not :http.