Reputation: 1617
I'm following the Rails 4 In action book and I'm running into the following error:
No route matches [POST] "/sessions/new"
I'm not sure why, as I've followed the tutorial to a T. Which leaves me to believe the tutorial itself is flawed. Anyhow, for some reason it's posting to sessions#new when it should be posting to sessions#create. What am I doing wrong?
sessions_controller.rb
class SessionsController < ApplicationController
def new
end
def create
user = User.where(:name => params[:signin][:name]).first
if user && user.authenticate(params[:signin][:password])
session[:user_id] = user.id
flash[:notice] = "Signed in successfully."
redirect_to root_url
else
flash[:error] = "Sorry."
render :new
end
end
end
sessions/new.html.erb
<h1>Sign in</h1>
<%= form_for :signin, method: "POST" do |f| %>
<p>
<%= f.label :name %><br />
<%= f.text_field :name %>
</p>
<p>
<%= f.label :password %><br />
<%= f.password_field :password %>
</p>
<%= f.submit "Sign in" %>
<% end %>
routes.rb
get "/signin", to: "sessions#new"
post "/signin", to: "sessions#create"
Upvotes: 1
Views: 1373
Reputation: 8826
You are correct there is an error in this book.
When you have a form for tag
<%= form_for :signin, method: "POST" do |f| %>
If rails doesn't know what :signin
means, then it will simply copy the current url and will submit the form to that url (in this case 'sessions/new'), using the post verb (whether you specify it or not!)
<form accept-charset="UTF-8" action="/sessions/new" method="post">
....
Obviously, that's not necessarily what you want because you don't have a /sessions/new for post HTTP verb, I think the easiest solution would be to specify a route
post "/signin", to: "sessions#create", as: "signin"
and in your form_for
<%= form_for signin_path do |f| %>
Upvotes: 5