Michael Hartl ch9 : how to sign up - ruby-on-rails

I’ve completed Michael Hartl ch 9 and have no error in testing.
But I could not sign up...
It returns error as below even so previously I be able to sign up..login works fine.
How to fix it and be able to sign up?
Should I merge sign up branch? But doing that I could loose all changes.. Could something be done about sign up form this more advance branch?
Error:
No route matches [POST] "/signup"
routes.rb:
Rails.application.routes.draw do
root 'static_pages#home'
get '/help', to: 'static_pages#help'
get '/about', to: 'static_pages#about'
get '/contact', to: 'static_pages#contact'
get '/signup', to: 'users#new'
get '/login', to: 'sessions#new'
post '/login', to: 'sessions#create'
delete '/logout', to: 'sessions#destroy'
resources :users
end
thanks.
Thanks everybody for answers.
It works now.
One more question related.
When users sign up - they could directly participate in website. It is no good since they need to get confirmation by email and only that they could participate.
How it could be implemented?
I think it is in the solutions Michael Hartl and I even implemented it for Rails 4, but could not remember what need to change..
What files need to be changed to allow users participate in website only after getting confirmation by email.
thanks.

The error is very clear and crisp, you don't have a route for users#create, you need to implement that action and it should work.
Go through this section in the book..

No route matches [POST] "/signup"
You should have post '/signup', to: 'users#create' in your routes.

You need to add
post '/signup', to: 'users#create'
And write create method in
class UsersController < ApplicationController
def create
# Create User with signup parameterss
end
end

Related

My routes file doesn't match expected result

Thanks in advance for any help.
I'm working my way through Michael Hartl's "learn enough" RoR lessons and am at the point where we're working with authenticating users via sessions.
Per the lesson, I've just run rails generate controller Sessions new and nothing blew chunks:
$ rails generate controller Sessions new
Running via Spring preloader in process 4407
create app/controllers/sessions_controller.rb
route get 'sessions/new'
invoke erb
create app/views/sessions
create app/views/sessions/new.html.erb
invoke test_unit
create test/controllers/sessions_controller_test.rb
invoke helper
create app/helpers/sessions_helper.rb
invoke test_unit
invoke assets
invoke coffee
create app/assets/javascripts/sessions.coffee
invoke scss
create app/assets/stylesheets/sessions.scss
However, there's a discrepancy between what the lesson says routes.rb should look like and what it actually does look like.
Expected result in routes.rb, as implied by the lesson:
Rails.application.routes.draw do
root 'static_pages#home'
get '/help', to: 'static_pages#help'
get '/about', to: 'static_pages#about'
get '/contact', to: 'static_pages#contact'
get '/signup', to: 'users#new'
get '/login', to: 'sessions#new'
post '/login', to: 'sessions#create'
delete '/logout', to: 'sessions#destroy'
resources :users
end
Actual result in routes.rb:
Rails.application.routes.draw do
get 'sessions/new'
root 'static_pages#home'
get '/help', to: 'static_pages#help'
get '/about', to: 'static_pages#about'
get '/contact', to: 'static_pages#contact'
get '/signup', to: 'users#new'
post '/signup', to: 'users#create'
resources :users
end
Am I missing something obvious? Why the difference?
I feel like there's a missing chapter between here and the last one, which only explains the really high level difference between browser-close-ending sessions and cookie-expired sessions.
You ran rails generate controller Sessions new, which means you want to generate a controller with the new action only. By default, new generates the view route (GET) and the actual resource creation route (POST).
To create the controller and routes following the CRUD pattern, you should run rails generate controller Sessions.
Solved.
The reason for the discrepancy is that rails generate controller Sessions new only generates the GET route #vnbrs mentioned.
The lesson calls for 3 routes that need to be supported: a GET request to the login form, a POST request to create the session, and a DELETE request to destroy the session.
Those need to be added to routes.rb manually:
get '/login', to: 'sessions#new'
post '/login', to: 'sessions#create'
delete '/logout', to: 'sessions#destroy'
Beginner's disorientation, I couldn't see the forest for the trees and broke my brain. (P.S. I don't recommend trying to tackle this tutorial discontinuously over a series of months...your brain does NOT pick up where it left off.)

Rails devise 4 matched routes

i have hit an error with devise, on rails 4 in terms of routing. I wish to have the /users/sign_up route matched to /login. the match :to method yielded no results.
thank you in advance
Add the following to your config/routes.rb:
devise_scope :user do
get '/login', to: 'devise/sessions#new'
end

Showing username in url without controller name

Hope everyone's good this morning. Been learning rails lately, and been working on a little "social" app for practice. I've looked around for a good answer for this, but couldn't find the right thing for me. Here's what I'm trying to figure out now:
By default, the url is hi.com/user/12, and so far I've changed that to /user/name. Everything works fine there. But of course, I want to take it further and do hi.com/name (mostly because I want to learn how it's done properly).
Here's my (abbreviated) routes:
resources :users do
member do
get :following, :followers
end
end
root to: 'pages#home'
match '/help', to: 'pages#help'
match '/about', to: 'pages#about'
match '/contact', to: 'pages#contact'
match '/signup', to: 'users#new'
match '/signin', to: 'sessions#new'
match '/signout', to: 'sessions#destroy', via: :delete
Here's the show view from the controller:
def show
#user = User.find_by_username(params[:id])
#tweets = #user.tweets.paginate(page: params[:page])
end
Now what I've tried is to stick match ':username', to: 'users#show' in my routes, and then change find_by_username(params[:id]) in the controller to find_by_username(params[:username]). This actually works really well, and shows all proper user info on hi.com/name. The following and followers are still (as expected) on user/name/following (and they work fine). However, all static pages break, including /signout (kinda important :p), and while /users still shows an index of all users, users/name throws an error (if /name works, then I wouldn't need /users/name anyway). The error being undefined method `tweets' for nil:NilClass in the users controller.
Again what I'm trying to accomplish is hi.com/username and hi.com/username/following, etc. Also need my static pages to still work. I have everything working with /users/name, but I want to learn how to make it work this way too.
Thanks everyone, I appreciate it!
Basically, it's easy but it has side effects.
Just add at the end of your routes.rb:
get '/:id', to: 'user#show'
But, a user named about, or users or pages won't be able to see their profile, because the path is used earlier in your routes.rb.

Rails routes error

I am following along with Michael Hartl's Ruby on Rails Tutorial 2nd Edition and have reached the signin/signout section of the book.
So far I can create a new user (or in my case landlord) and log in with the new credentials. The problem I have is when signing out. I click "signout" and get a route error saying:
No route matches [GET] "/signout"
Below are code snippets. Any help would be very appreciated!
rake routes output
landlords GET /landlords(.:format) landlords#index
POST /landlords(.:format) landlords#create
new_landlord GET /landlords/new(.:format) landlords#new
edit_landlord GET /landlords/:id/edit(.:format) landlords#edit
landlord GET /landlords/:id(.:format) landlords#show
PUT /landlords/:id(.:format) landlords#update
DELETE /landlords/:id(.:format) landlords#destroy
properties GET /properties(.:format) properties#index
POST /properties(.:format) properties#create
new_property GET /properties/new(.:format) properties#new
edit_property GET /properties/:id/edit(.:format) properties#edit
property GET /properties/:id(.:format) properties#show
PUT /properties/:id(.:format) properties#update
DELETE /properties/:id(.:format) properties#destroy
sessions POST /sessions(.:format) sessions#create
new_session GET /sessions/new(.:format) sessions#new
session DELETE /sessions/:id(.:format) sessions#destroy
root / content_pages#home
content_pages_home GET /content_pages/home(.:format) content_pages#home
help /help(.:format) content_pages#help
questions /questions(.:format) content_pages#questions
signup /signup(.:format) landlords#new
signin /signin(.:format) sessions#new
signout DELETE /signout(.:format) sessions#destroy
routes.rb file
resources :landlords
resources :properties
resources :sessions, only: [:new, :create, :destroy]
root :to => 'content_pages#home'
get "content_pages/home"
match '/help', to: 'content_pages#help'
match '/questions', to: 'content_pages#questions'
match '/signup', to: 'landlords#new'
match '/signin', to: 'sessions#new'
match '/signout', to: 'sessions#destroy', via: :delete
link to signout
<%= link_to "Signout", signout_path, method: "delete" %>
sessions controller
def destroy
sign_out
redirect_to root_path
end
The via: option in the following code restricts the request to the delete method:
match '/signout', to: 'sessions#destroy', via: :delete
You'll need to make one that works with the 'get' method
Check out the Rails Routing guide

Ruby on Rails Routing changes not working

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

Resources