Saturday, February 23, 2013

Gotchas during Chapter 8 of the Ruby on Rails tutorial

During the Ruby on Rails tutorial, I encountered several errors during Chapter 8. Luckily, I solved quite a few of them and learnt a few things about debugging along the way.

Problem: Cannot create users
The first thing that caught me was the error regarding creation of users. I could not create the user.

Code: app/controllers/sessions_controller.rb

def create
    user = User.find_by_email(params[:session][:email])
    if user && user.authenticate(params[:session][:password])
      sign_in user
      redirect_to user
    else
      flash.now[:error] = 'Invalid email/password combination' # Not quite right!
      render 'new'
    end

Reading the logs, I saw this message on the line where "find_by_email" is called. I was extremely puzzled as to why this message occurred.

Error message:
SELECT "users".* FROM "users" WHERE "users"."email" = NULL LIMIT 1

Why it happened:
You can't access the values of "email" and "password" through params[:session][:email].

The sessions hash looks like:

utf8: 
authenticity_token: 1D72gydJcrOzGslhOnfAotmkEUtghtQmOhEZRQGWpiw=
sessions: !ruby/hash:ActiveSupport::HashWithIndifferentAccess
  email: 'user@example.com'
  password: 'foobar'


Solution:
You can access the email and password values of the params through 2 methods:

params["sessions"]["email"]
params[:email]

Updated code:
def create
    user = User.find_by_email(params["sessions"]["email"])
    if user && user.authenticate(params["session"]["password"])
      sign_in user
      redirect_to user
    else
      flash.now[:error] = 'Invalid email/password combination' # Not quite right!
      render 'new'
    end

Problem: Cannot authenticate users in authentication_pages_spec.rb
As Postgresql is case-sensitive, we need to make sure the emails are downcased.

      before do
        fill_in "Email",     with: user.email.downcase
        fill_in "Password",  with: user.password
        click_button "Sign in"
        save_and_open_page    # useful to see the page that is generated
      end
The original code was 
user.email.upcase