Ruby on Rails Routing changes not working - ruby-on-rails

Recently I've tried to update my routes to be more specific in the routing.rb file:
resources :users
match '/signup', :to => 'users#new'
I removed the resources :users and changed the above to
match 'users/new' => 'users#new'
match 'users/show/:id' => 'users#show', :as => :users_show
match 'users/edit' => 'users#edit'
match '/signup', :to => 'users#new'
But when I try to click on the same link that I've had before in my layout page using the signup_path (http://localhost:3000/signup), I get the following error:
undefined method `users_path' but I am not using users_path anywhere
Shouldn't it still work? I haven't changed anything else in the other pages. The controller and actions are still the same.
Thanks!

What it tells is that you don have helper method named "users_path", which is created by resources in routes.rb.
Check by yourself with rake routes, what you get with your example:
users_new /users/new.(:format) {:controller=>"users", :action=>"new"}
users_show /users/show/:id(.:format) {:controller=>"users", :action=>"show"}
users_edit /users/edit(.:format) {:controller=>"users", :action=>"edit"}
(and no, you don't need forward slash at the beginning of path).
You defined only routes for some pages (show/new/edit), but you don't have path for index/create/update/destroy actions. Add resource back to routes.rb and check which routes it generates. Remember that by default your match-ed routes match all requests, not specific HTTP methods (like with resource). If you want to fully reassemble this behavior, take a look at documentation (at http://api.rubyonrails.org search for "match") and :via parameter.
Also why do you want to remove resource, and add all paths by yourself? If you want to limit available routes, then there are :only/:except options, you can also pass block and add routes by yourself, just check documentation (at http://api.rubyonrails.org and search for "resources" - it's shame I no longer can get link to specific documentation page and from Rails documentation).

I think basicxman is on the right track. You need a leading '/' in all your routes
Change:
match 'users/new' => 'users#new'
match 'users/show/:id' => 'users#show', :as => :users_show
match 'users/edit' => 'users#edit'
To:
match '/users/new' => 'users#new'
match '/users/show/:id' => 'users#show', :as => :users_show
match '/users/edit' => 'users#edit'
Also, do you still have the resources :users line at the top of your routes.rb? That'll also be necessary.

You have to add a route to create action as well. Probably your signup form points to users_path with POST method which is basically the create action. So add to your routes the following
match 'users' => 'users#create', :via => :post, :as=>:users
For more customization info please see the Rails routing guide

Related

How to remove /posts/ from URL?

How can I also show a blog post without /posts/ in the URL?
http://www.anthonygalli.com/posts/i-walk-the-line
http://www.anthonygalli.com/posts/50-shades-of-galli
http://www.anthonygalli.com/posts/tips-for-regaining-momentum
Shortened Version (Goal of Question):
http://www.anthonygalli.com/i-walk-the-line
http://www.anthonygalli.com/50-shades-of-galli
http://www.anthonygalli.com/tips-for-regaining-momentum
I have post as a MVC.
routes.rb
resources :posts
get 'about' => 'posts#about'
get 'feed' => 'posts#feed'
get 'subscribe' => 'posts#subscribe'
Change your routes.rb to:
resources :posts, path: '/' do
collection do
get 'about'
get 'feed'
get 'subscribe'
end
end
For documentation on Rails routing check: http://guides.rubyonrails.org/routing.html
Your routes should be updated to look something like this:
resources :posts
get 'about' => 'posts#about'
get 'feed' => 'posts#feed'
get 'subscribe' => 'posts#subscribe'
get ':id' => 'posts#show', :as => :post_by_slug
That as option will be important for linking to your new route if you want to link to the /post/-less paths:
<%= link_to post.title, post_by_slug_path(post) %>
P. S. I believe that the new route will need to be listed last in your routes so that the routes before it can have precedence. (Otherwise, trying to visit /about would try to load a post with a slug named about instead of the posts#about action. You should try this and see if that's true.)
Resource generates the standard CRUD urls, so you have to specify the posts route specifically. Something like this
get '/desired-url' => 'posts#index'

Matching and Routes in Rails

I generated a controller and changed the routes but opening the links yields errors on my local server.
Generating controller and routes
rails generate controller StaticPages home about team contact
Change routes.rb
MyApp::Application.routes.draw do
root to: 'static_pages#home'
match '/about', to: 'static_pages#about'
match '/team', to: 'static_pages#team'
match '/contact', to: 'static_pages#contact'
end
The root path work but none of the 'about, 'team', or 'contact' links work. This is the error I get:
"You should not use the match method in your router without specifying an HTTP method. If you want to expose your action to both GET and POST, add via: [:get, :post] option. If you want to expose your action to GET, use get in the router: Instead of: match "controller#action" Do: get "controller#action""
Why can't I use 'match'?
match method has been deprecated.
Use get for GET and post for POST.
get '/about', to: 'static_pages#about'
You can use match, you've gotta add a via: option:
match '/about', to: 'static_pages#about', via: :get
match '/team', to: 'static_pages#team', via: :get
match '/contact', to: 'static_pages#contact', via: :get
You can also pass other HTTP verbs to via: if you need to, like via: [:get, :post]
Source: Rails Routing Guide
First, you must specify the HTTP method by adding via: :get at the end of match 'st' => 'controller#action
And it's better to use get '/home', to: 'static_pages#home'
But, there is a problem, that your code doesn't follow RESTful, that only support 7 actions: index, new, edit, create, update, show and destroy.
These are 2 solutions:
SOL 1: Put them in different controller (homes, abouts..) and all of these controllers have action index.
SOL 2: If it's too much work, we can match them to show action. We use static_pages controller, and each page (home, about) will be a item.
The routes will look likes
/static_pages/home
/static_pages/about
I know it isn't good because of the prefix static_pages.
We can easily get rid of this by adding a custom routes at the end of routes file:
get '/:id', to: 'static_pages#show'
That's it. And if you think it's too much work (I think so too), check out this gem High Voltage. Have fun.

Not getting a [:id] parameter from url, Default route is not working

When I request a URL as follows:
http://localhost:3000/password_resets/edit/4RghIKJNygEDswIuuCo
I'm not getting the [:id] parameter, i.e. 4RghIKJNygEDswIuuCo.
Here is my route file, are there any modifications required for this?
ActionController::Routing::Routes.draw do |map|
match 'primary', :to => 'pages#primary', :as => "primary"
match 'admins', :to => 'admin_users#list', :as => "admins"
match 'login', :to => 'user_sessions#new', :as => "login"
match 'logout', :to => 'user_sessions#destroy', :as => "logout"
root :to =>"public#index"
match 'HFA/:id/' => 'public#show'
match 'HFA/:id/:uid' =>'public#show'
match 'public/projectview/:projectid/' => 'public#projectview'
map.connect ':controller/:action/:id.:format'
map.connect ':controller/:action/:id'
resources :users
resources :usertypes
resources :user_sessions
end
The default is /controller/:id/edit, following the REST architecture.
Do you really want to change this?
If so, verify the order of the declarations:
Rails routes are matched in the order they are specified, so if you
have a resources :photos above a get 'photos/poll' the show action’s
route for the resources line will be matched before the get line. To
fix this, move the get line above the resources line so that it is
matched first.
http://guides.rubyonrails.org/routing.html#crud-verbs-and-actions
and check your availables routes with the rake routes command:
http://guides.rubyonrails.org/routing.html#inspecting-and-testing-routes
if you put match instead of 'get' you will get all http (GET, POST, PUT, DELETE) route verbs
get 'password_resets/:id/edit', to: 'password_reset#create', as: :send_password_reset
the 'to:' defines the controller method, 'as:' defines the path name, 'get' defines the route verb and ':id' is the token created by this line in app/views/user_mailer/password_reset.text.erb
<%= send_password_reset_url(#user.password_reset_token) %>
run "rake routes" command and check the routes for "password_resets/edit/4RghIKJNygEDswIuuCo".

Chapter 5 of Hartl book Why does routing requires get() for user.new?

Around listing 5.29 of the Hartl rails tutorial (http://ruby.railstutorial.org/) there is a discussion of a routing error that forces you to call the get method on users/new and not just a match method. This is later rectified by calling to the resources method in the next chapter.
My general question is why don't we have to call get() on the PagesController actions in the following listing.
#5.29
SampleApp::Application.routes.draw do
get "users/new"
match '/signup', :to => 'users#new'
match '/contact', :to => 'pages#contact'
match '/about', :to => 'pages#about'
match '/help', :to => 'pages#help'
root :to => 'pages#home'
end
The difference is in the types of HTTP requests the routes will match.
By using get "users/new" the route will only match HTTP GET requests.
match "users/new" would actually match all types of HTTP requests.
You can use get instead of match for your other routes if you only expect GET requests for them (which appears to be the case).

Refactoring 'match' in routes.rb

I've read official guide but still have misunderstanding.
Is this code able for refactoring?
match '/help', :to => 'home#help'
match '/contact', :to => 'home#contact'
match '/about', :to => 'home#about'
help, contact and about are the only actions in the controller home.
I did this on a hunch and it's not mentioned in the documentation, but it looks like it works (I'm on rails 3.1):
controller :home do
get 'help'
get 'contact'
get 'about'
end
This also creates the help_url, help_path, etc helpers.
One warning though, this restricts the http verbs to GET. If you have a POST action (as an example, for a contact form), you could do either:
controller :home do
get 'help'
match 'contact', :via => [:get, :post]
get 'about'
end
or just:
controller :home do
get 'help'
match 'contact'
get 'about'
end
which will allow all http verbs on the contact route. But I find it better to be explicit about the accepted verbs.
You should be able to use rails shorthand here and do:
match 'home/help'
match 'home/contact'
match 'home/about'
Since the method names match this should work.
you could of course do
match '/:action', :controller => :home, :constraints => { :action => /^(help|contact|about)$/ }
but this is neither prettier, nor really shorter

Resources