I am new to rails and am following Hartl's rails tutorial. I'm trying to set up the user login form but am facing this error upon submission of valid credentials:-
undefined method `[]' for nil:NilClass
Extracted source (around line #7):
6 def create
7 user = User.find_by(email: params[:session][:email].downcase)
8 if user && user.authenticate(params[:session][:password])
9 log_in user
10 redirect_to user
It is coming from this file which is trying to create a session:-
class SessionsController < ApplicationController
def new
end
def create
user = User.find_by(email: params[:session][:email].downcase)
if user && user.authenticate(params[:session][:password])
log_in user
redirect_to user
else
flash.now[:danger] = 'Invalid email/password combination'
render 'new'
end
end
I tried to debug a little and found that params[:session] returns nil. I confirmed it using byebug. I changed [:session]
to [:sessions]
and the login form submitted successfully, which was weird because in the tutorial it is just [:session]
. But the other weird thing is that when I changed this, my rails tests failed showing the following 2 errors:-
ERROR["test_login_with_invalid_information", UsersLoginTest, 0.8645880669937469]
test_login_with_invalid_information#UsersLoginTest (0.86s)
NoMethodError: NoMethodError: undefined method `[]' for nil:NilClass
app/controllers/sessions_controller.rb:7:in `create'
test/integration/users_login_test.rb:13:in `block in <class:UsersLoginTest>'
ERROR["test_login_with_valid_information", UsersLoginTest, 0.887510354994447]
test_login_with_valid_information#UsersLoginTest (0.89s)
NoMethodError: NoMethodError: undefined method `[]' for nil:NilClass
app/controllers/sessions_controller.rb:7:in `create'
test/integration/users_login_test.rb:22:in `block in <class:UsersLoginTest>'
It's from this test:-
require 'test_helper'
class UsersLoginTest < ActionDispatch::IntegrationTest
def setup
@user = users(:michael)
end
test "login with invalid information" do
get login_path
assert_template 'sessions/new'
post login_path, params: { session: { email: "", password: "" } }
assert_template 'sessions/new'
assert_not flash.empty?
get root_path
assert flash.empty?
end
test "login with valid information" do
get login_path
post login_path, params: { session: { email: @user.email,
password: 'password' } }
assert_redirected_to @user
follow_redirect!
assert_template 'users/show'
assert_select "a[href=?]", login_path, count: 0
assert_select "a[href=?]", logout_path
assert_select "a[href=?]", user_path(@user)
end
end
This is really odd.
In summary, I am stuck between getting the form to submit successfully on localhost by changing [:session] to [:sessions] and having my rails test fail or leave it at [:session] and have my tests pass and the actual form fail to submit.
I don't know how to process this error. Would love to have some light thrown on it.
Update:-
I'm using Rails 5.0.2 (but following the tutorial written using 5.0.1). (update - I just tried downgrading to 5.0.1 and it doesn't make a difference).
The users controller with the create action:-
class UsersController < ApplicationController
def show
@user = User.find(params[:id])
end
def new
@user = User.new
end
def create
@user = User.new(user_params)
if @user.save
flash[:success] = "Welcome to your profile page!"
redirect_to @user
else
render 'new'
end
end
private
def user_params
params.require(:user).permit(:name, :email, :password,
:password_confirmation)
end
end
I used (byebug) near the code that's giving me trouble and got this when I entered "params" in the terminal:-
<ActionController::Parameters {"utf8"=>"✓",
"authenticity_token"=>"CZUudm++VEWSxWUUxpDD5xI+oTezbzVE9lcX5Up5P5UAwl2zG+p
Oic5e6Sh08Vu2iyvQ0TAlHJSEuA+j/+C7jA==", "sessions"=>
<ActionController::Parameters {"email"=>"dude@email.com",
"password"=>"password"} permitted: false>, "commit"=>"Log in",
"controller"=>"sessions", "action"=>"create"} permitted: false>