lundi 8 mai 2017

undefined method `[]' for nil:NilClass error while submitting form; and rails test conflicts with results on deployment

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.

Aucun commentaire:

Enregistrer un commentaire