Railscasts #241 NoMethodError undefined method `[]' for nil:NilClass

Sakshi Jain picture Sakshi Jain · Jan 10, 2014 · Viewed 7.1k times · Source

There is a NoMethodError in SessionsController#create. The twitter authentication page occurs but the callback URL is not working. The page is not being rendered to the website after twitter authentication. Here is the code in different files.

In routes.rb

Blog::Application.routes.draw do
  root :to => "posts#index"

  match "/auth/:provider/callback" => "sessions#create"
  match "/signout" => "sessions#destroy", :as => :signout

  resources :posts
end

In sessions_controller.rb

class SessionsController < ApplicationController
  def create
    auth = request.env["omniauth.auth"]
    user = User.find_by_provider_and_uid(auth["provider"], auth["uid"]) || User.create_with_omniauth(auth)
    session[:user_id] = user.id
    redirect_to root_url, :notice => "Signed in!"
  end

  def destroy
    session[:user_id] = nil
    redirect_to root_url, :notice => "Signed out!"
  end
end

In user.rb

class User < ActiveRecord::Base
  def self.create_with_omniauth(auth)
    create! do |user|
      user.provider = auth["provider"]
      user.uid = auth["uid"]
      user.name = auth["user_info"]["name"]
    end
  end
end

Full Trace:

app/models/user.rb:6:in `block in create_with_omniauth'
activerecord (3.2.0) lib/active_record/validations.rb:40:in `create!'
app/models/user.rb:3:in `create_with_omniauth'
app/controllers/sessions_controller.rb:4:in `create'
actionpack (3.2.0) lib/action_controller/metal/implicit_render.rb:4:in `send_action'
actionpack (3.2.0) lib/abstract_controller/base.rb:167:in `process_action'
actionpack (3.2.0) lib/action_controller/metal/rendering.rb:10:in `process_action'
actionpack (3.2.0) lib/abstract_controller/callbacks.rb:18:in `block in process_action'
activesupport (3.2.0) lib/active_support/callbacks.rb:414:in `_run__168269495__process_action__8122527__callbacks'
activesupport (3.2.0) lib/active_support/callbacks.rb:405:in `__run_callback'
activesupport (3.2.0) lib/active_support/callbacks.rb:385:in `_run_process_action_callbacks'
activesupport (3.2.0) lib/active_support/callbacks.rb:81:in `run_callbacks'
actionpack (3.2.0) lib/abstract_controller/callbacks.rb:17:in `process_action'
actionpack (3.2.0) lib/action_controller/metal/rescue.rb:29:in `process_action'
actionpack (3.2.0) lib/action_controller/metal/instrumentation.rb:30:in `block in process_action'
activesupport (3.2.0) lib/active_support/notifications.rb:123:in `block in instrument'
activesupport (3.2.0) lib/active_support/notifications/instrumenter.rb:20:in `instrument'
activesupport (3.2.0) lib/active_support/notifications.rb:123:in `instrument'
actionpack (3.2.0) lib/action_controller/metal/instrumentation.rb:29:in `process_action'
actionpack (3.2.0) lib/action_controller/metal/params_wrapper.rb:205:in `process_action'
activerecord (3.2.0) lib/active_record/railties/controller_runtime.rb:18:in `process_action'
actionpack (3.2.0) lib/abstract_controller/base.rb:121:in `process'
actionpack (3.2.0) lib/abstract_controller/rendering.rb:45:in `process'
actionpack (3.2.0) lib/action_controller/metal.rb:203:in `dispatch'
actionpack (3.2.0) lib/action_controller/metal/rack_delegation.rb:14:in `dispatch'
actionpack (3.2.0) lib/action_controller/metal.rb:246:in `block in action'
actionpack (3.2.0) lib/action_dispatch/routing/route_set.rb:66:in `call'
actionpack (3.2.0) lib/action_dispatch/routing/route_set.rb:66:in `dispatch'
actionpack (3.2.0) lib/action_dispatch/routing/route_set.rb:30:in `call'
journey (1.0.4) lib/journey/router.rb:68:in `block in call'
journey (1.0.4) lib/journey/router.rb:56:in `each'
journey (1.0.4) lib/journey/router.rb:56:in `call'
actionpack (3.2.0) lib/action_dispatch/routing/route_set.rb:570:in `call'
omniauth (1.1.4) lib/omniauth/strategy.rb:401:in `call_app!'
omniauth (1.1.4) lib/omniauth/strategy.rb:363:in `callback_phase'
omniauth-oauth (1.0.1) lib/omniauth/strategies/oauth.rb:58:in `callback_phase'
omniauth (1.1.4) lib/omniauth/strategy.rb:226:in `callback_call'
omniauth (1.1.4) lib/omniauth/strategy.rb:182:in `call!'
omniauth (1.1.4) lib/omniauth/strategy.rb:164:in `call'
omniauth (1.1.4) lib/omniauth/builder.rb:49:in `call'
actionpack (3.2.0) lib/action_dispatch/middleware/best_standards_support.rb:17:in `call'
rack (1.4.5) lib/rack/etag.rb:23:in `call'
rack (1.4.5) lib/rack/conditionalget.rb:25:in `call'
actionpack (3.2.0) lib/action_dispatch/middleware/head.rb:14:in `call'
actionpack (3.2.0) lib/action_dispatch/middleware/params_parser.rb:21:in `call'
actionpack (3.2.0) lib/action_dispatch/middleware/flash.rb:242:in `call'
rack (1.4.5) lib/rack/session/abstract/id.rb:210:in `context'
rack (1.4.5) lib/rack/session/abstract/id.rb:205:in `call'
actionpack (3.2.0) lib/action_dispatch/middleware/cookies.rb:338:in `call'
activerecord (3.2.0) lib/active_record/query_cache.rb:64:in `call'
activerecord (3.2.0) lib/active_record/connection_adapters/abstract/connection_pool.rb:443:in `call'
actionpack (3.2.0) lib/action_dispatch/middleware/callbacks.rb:28:in `block in call'
activesupport (3.2.0) lib/active_support/callbacks.rb:405:in `_run__208198798__call__80088063__callbacks'
activesupport (3.2.0) lib/active_support/callbacks.rb:405:in `__run_callback'
activesupport (3.2.0) lib/active_support/callbacks.rb:385:in `_run_call_callbacks'
activesupport (3.2.0) lib/active_support/callbacks.rb:81:in `run_callbacks'
actionpack (3.2.0) lib/action_dispatch/middleware/callbacks.rb:27:in `call'
actionpack (3.2.0) lib/action_dispatch/middleware/reloader.rb:65:in `call'
actionpack (3.2.0) lib/action_dispatch/middleware/remote_ip.rb:31:in `call'
actionpack (3.2.0) lib/action_dispatch/middleware/debug_exceptions.rb:16:in `call'
actionpack (3.2.0) lib/action_dispatch/middleware/show_exceptions.rb:56:in `call'
railties (3.2.0) lib/rails/rack/logger.rb:26:in `call_app'
railties (3.2.0) lib/rails/rack/logger.rb:16:in `call'
actionpack (3.2.0) lib/action_dispatch/middleware/request_id.rb:22:in `call'
rack (1.4.5) lib/rack/methodoverride.rb:21:in `call'
rack (1.4.5) lib/rack/runtime.rb:17:in `call'
activesupport (3.2.0) lib/active_support/cache/strategy/local_cache.rb:72:in `call'
rack (1.4.5) lib/rack/lock.rb:15:in `call'
actionpack (3.2.0) lib/action_dispatch/middleware/static.rb:53:in `call'
railties (3.2.0) lib/rails/engine.rb:479:in `call'
railties (3.2.0) lib/rails/application.rb:220:in `call'
rack (1.4.5) lib/rack/content_length.rb:14:in `call' 
railties (3.2.0) lib/rails/rack/log_tailer.rb:14:in `call'
rack (1.4.5) lib/rack/handler/webrick.rb:59:in `service'
/home/sakshi/.rvm/rubies/ruby-2.0.0-p195/lib/ruby/2.0.0/webrick/httpserver.rb:138:in `service'
/home/sakshi/.rvm/rubies/ruby-2.0.0-p195/lib/ruby/2.0.0/webrick/httpserver.rb:94:in `run'
/home/sakshi/.rvm/rubies/ruby-2.0.0-p195/lib/ruby/2.0.0/webrick/server.rb:295:in `block in start_thread'

Console:

NoMethodError (undefined method `[]' for nil:NilClass):
  app/models/user.rb:6:in `block in create_with_omniauth'
  app/models/user.rb:3:in `create_with_omniauth'
  app/controllers/sessions_controller.rb:4:in `create'

Answer

Ju Liu picture Ju Liu · Jan 10, 2014

In line 6 of app/models/user.rb:

user.name = auth["user_info"]["name"]

The auth hash doesn't have a value for the "user_info" key, so it returns nil; then you try to call the [] method on nil, which raises the exception.

Try adding a p auth in the block to verify the auth hash contents:

class User < ActiveRecord::Base
  def self.create_with_omniauth(auth)
    create! do |user|
      puts "DEBUG " + "=" * 50
      p auth
      user.provider = auth["provider"]
      user.uid = auth["uid"]
      user.name = auth["user_info"]["name"]
    end
  end
end