Reputation: 171
The error occured after submitting "Create" account, no matter I entered password or not, the error message is below:
No route matches [POST] "/users/create"
I built the page of registration, this is my new.html.erb
in users
file
<div class="center hero-unit">
<% @page_title = "Sign up" %>
<h1>Sign Up</h1>
<%= form_for(:user, :url => {:controller => 'users', :action => 'create'}) do |f| %>
<p> First name:</br> <%= f.text_field :first %> </p>
<p> Last name:</br> <%= f.text_field :last %> </p>
<p> Email:</br> <%= f.text_field :email %> </p>
<p> Password:</br> <%= f.password_field :password %></p>
<p> Password Confirmation:</br> <%= f.password_field :password_confirmation %> </p>
<%= f.submit :Create, class:"btn btn-large btn-primary" %>
<%= link_to "Cancel", root_path, class:"btn btn-large btn-primary" %>
<% end %>
<% if @user.errors.any? %>
<ul class="Signup_Errors">
<% for message_error in @user.errors.full_messages %>
<li>* <%= message_error %></li>
<% end %>
</ul>
<% end %>
</div>
The route.rb
is:
Rails.application.routes.draw do
get 'sessions/login'
get 'sessions/main'
get 'sessions/profile'
get 'sessions/setting'
get 'users/new'
get 'home/index'
root 'home#index'
match '/about', to: 'home#about', via: 'get'
match '/signup', to: 'users#new', via: 'get'
match ':controller(/:action(/:id))(.:format)', via: 'get'
match '/login', to: 'sessions#login', via: 'get'
match '/logout', to: 'sessions#logout', via: 'get'
match '/main', to: 'sessions#main', via: 'get'
match '/profile', to: 'sessions#profile', via: 'get'
match '/setting', to: 'sessions#setting', via: 'get'
end
And the users_controller.rb
is:
class UsersController < ApplicationController
before_filter :save_login_state, :only => [:new, :create]
def new
@user = User.new
end
def create
@user = User.new(user_params)
if @user.save
flash[:notice] = 'You signed up succefully!'
flash[:color] = 'valid'
else
flash[:notice] = 'Form is invalid.'
flash[:color] = 'invalid'
render 'new'
end
end
private
def user_params
params.require(:user).permit(:email, :password, :password_confirmation)
end
end
The user.rb
in models is:
class User < ActiveRecord::Base
#attr_accessible :email, :password, :password_confirmation
attr_accessor :password
EMAIL_REGEX = /\b[A-Z0-9._%a-z\-]+@(?:[A-Z0-9a-z\-]+\.)+[A-Za-z]{2,4}\z/
validates :username, :presence => true, :uniqueness => true, :length => { :in => 3..20 }
validates :email, :presence => true, :uniqueness => true, :format => EMAIL_REGEX
validates :password, :confirmation => true #password_confirmation attr
validates_length_of :password, :in => 6..20, :on => :create
before_save :encrypt_password
after_save :clear_password
#attr_accessible :email, :password, :password_confirmation
def encrypt_password
if password.present?
self.salt = BCrypt::Engine.generate_salt
self.encrypted_password= BCrypt::Engine.hash_secret(password, salt)
end
end
def clear_password
self.password = nil
end
def self.authenticate(email="", login_password="")
if EMAIL_REGEX.match(email)
user = User.find_by_email(email)
end
if user && user.match_password(login_password)
return user
else
return false
end
end
def match_password(login_password="")
encrypted_password == BCrypt::Engine.hash_secret(login_password, salt)
end
#attr_accessible :email, :password, :password_confirmation
end
I also created a password_hashing.rb
in models:
require 'digest/sha1'
encrypted_password= Digest::SHA1.hexdigest(password)
and a password_hasing_with_salt.rb
salt= Digest::SHA1.hexdigest("# We add {email} as unique value and #{Time.now} as random value")
encrypted_password= Digest::SHA1.hexdigest("Adding #{salt} to {password}")
In my migrate
, the thing is:
class CreateUsers < ActiveRecord::Migration
def change
create_table :users do |t|
t.string :first
t.string :last
t.string :email
t.string :encrypted_password
t.string :salt
t.timestamps
end
end
end
Also, the error message includes:
Routes
Routes match in priority from top to bottom
Helper HTTP Verb Path Controller#Action
Path / Url
sessions_login_path GET /sessions/login(.:format) sessions#login
sessions_main_path GET /sessions/main(.:format) sessions#main
sessions_profile_path GET /sessions/profile(.:format) sessions#profile
sessions_setting_path GET /sessions/setting(.:format) sessions#setting
users_new_path GET /users/new(.:format) users#new
home_index_path GET /home/index(.:format) home#index
root_path GET / home#index
courses_path GET /courses(.:format) courses#index
POST /courses(.:format) courses#create
new_course_path GET /courses/new(.:format) courses#new
edit_course_path GET /courses/:id/edit(.:format) courses#edit
course_path GET /courses/:id(.:format) courses#show
PATCH /courses/:id(.:format) courses#update
PUT /courses/:id(.:format) courses#update
DELETE /courses/:id(.:format) courses#destroy
about_path GET /about(.:format) home#about
signup_path GET /signup(.:format) users#new
GET /:controller(/:action(/:id))(.:format) :controller#:action
login_path GET /login(.:format) sessions#login
logout_path GET /logout(.:format) sessions#logout
main_path GET /main(.:format) sessions#main
profile_path GET /profile(.:format) sessions#profile
setting_path GET /setting(.:format) sessions#setting
How can I solve this problem please? Thank you for your time!
Upvotes: 2
Views: 1596
Reputation: 13181
form_for
accept several types of argument to cover different scenario, but in your case you want to pass your @user
model to it, so the form_for
know how to set a correct path and how to give the correct values to your text_field
s
Bottom line, instead of
form_for(:user, :url => {:controller => 'users', :action => 'create'}) do
...
You must use
form_for(@user) do
...
Additionally, when @user
is a new object (i.e created in your controller by User.new
) form_for
will automatically POST to your create
action. And when @user
is an existing record (i.e loaded from the database by User.find(params[:id]
) form_for
will PATCH to your update
action. It's automatic
Second point, it seems you have an incorrect route configuration as seen by the output of your rake routes
in your question. can you post your route.rb so we can advise?
So you need to remove get 'users/new'
from your route, and add resources :users
on top of your routes.rb file
And also this is not very clean: match ':controller(/:action(/:id))(.:format)', via: 'get'
I don't know what is the reason why you had to add it but I advise you to find an alternative and remove it.
Upvotes: 1