Nil Object in Signup form

Since I upgraded from Rails 1.8.6 to 2.3.5, I just noticed that I can no longer add new users through my Signup page. Here is the error: NoMethodError in UserController#signup

You have a nil object when you didn't expect it! You might have expected an instance of ActiveRecord::Base. The error occurred while evaluating nil.save!

/work/store/app/controllers/user_controller.rb:6:in `signup'

Here is my Controller, line 6 is @user.save!: def signup   return unless request.post?     @user.save!     redirect_back_or_default(:controller => 'grapher', :action => 'index')     flash[:notice] = "New User Successfully Created"     rescue ActiveRecord::RecordInvalid     render :action => 'signup' end

Here is my form: <% form_for :user do |f| -%> <label for= "first_name">First Name</label> <%= f.text_field :first_name %>

<label for= "last_name">Last Name</label> <%= f.text_field :last_name %>

<label for= "user_login">Login</label> <%= f.text_field :login %>

<label for= "user_email">Email</label> <%= f.text_field :email %>

<label for= "user_password">Password</label> <%= f.password_field :password %>

<label for= "user_password_confirmation">Confirm Password</label> <%= f.password_field :password_confirmation %> <%= submit_tag 'Sign up' %> <% end -%>

Here are my request parameters when I get the error: Request Parameters:

{"user"=>{"password_confirmation"=>"password", "first_name"=>"john", "last_name"=>"smith", "login"=>"jsmith", "password"=>"password", "email"=>"jsmith@email.com"}, "commit"=>"Sign up"}

It seems to me that I'm passing the correct params so I don't understand why I'm getting a "nil object" error?

Do you have a before filter where you set the @user variable? It’s complaining that the @user variable is nil.

No, I don't have any before statements in my controller, here is what it looks like:

class UserController < ApplicationController

public   def signup   return unless request.post?     @user.save!     redirect_back_or_default(:controller => 'grapher', :action => 'index')     flash[:notice] = "New User Successfully Created"     rescue ActiveRecord::RecordInvalid     render :action => 'signup' end

How do you assign the user params to the @user object?

Try adding before the @user.save! line the following

@user = User.new params[:user]

When I add that line to the top of my "def signup" code in the controller, I no longer get my signup form, instead, I get this message instead of seeing all the fields in my signup form:

NoMethodError in UserController#signup You have a nil object when you didn't expect it! You might have expected an instance of ActiveRecord::Base. The error occurred while evaluating nil.

jack

Since I upgraded from Rails 1.8.6 to 2.3.5, I just noticed that I can no longer add new users through my Signup page. Here is the error: NoMethodError in UserController#signup

You have a nil object when you didn't expect it! You might have expected an instance of ActiveRecord::Base. The error occurred while evaluating nil.save!

/work/store/app/controllers/user_controller.rb:6:in `signup'

Here is my Controller, line 6 is @user.save!: def signup return unless request.post? @user.save!

The error is telling you that @user is nil. There does not appear to be any code setting this up, Are you sure it ever worked?

redirect_back_or_default(:controller => 'grapher', :action => 'index') flash[:notice] = "New User Successfully Created"

This code also looks odd, how will it get to the flash line after the redirect? Though I may be missing what redirect_back_or_default is supposed to do.

rescue ActiveRecord::RecordInvalid

More odd looking code, or did the syntax for rescue change dramatically with Rails 2 from Rails 1

render :action => 'signup' end

Here is my form: <% form_for :user do |f| -%> <label for= "first_name">First Name</label> <%= f.text_field :first_name %>

<label for= "last_name">Last Name</label> <%= f.text_field :last_name %>

<label for= "user_login">Login</label> <%= f.text_field :login %>

<label for= "user_email">Email</label> <%= f.text_field :email %>

<label for= "user_password">Password</label> <%= f.password_field :password %>

<label for= "user_password_confirmation">Confirm Password</label> <%= f.password_field :password_confirmation %> <%= submit_tag 'Sign up' %> <% end -%>

Here are my request parameters when I get the error: Request Parameters:

{"user"=>{"password_confirmation"=>"password", "first_name"=>"john", "last_name"=>"smith", "login"=>"jsmith", "password"=>"password", "email"=>"jsmith@email.com"}, "commit"=>"Sign up"}

What action does the log show this is going to?

It seems to me that I'm passing the correct params so I don't understand why I'm getting a "nil object" error?

I think because @user is not getting setup.

Colin

When I add that line to the top of my "def signup" code in the controller, I no longer get my signup form, instead, I get this message instead of seeing all the fields in my signup form:

You'd want to put it after the check for request.post? Like some others here, i'm surprised this ever worked

Fred

redirect_back_or_default(:controller => ‘grapher’, :action => ‘index’) flash[:notice] = “New User Successfully Created”

This code also looks odd, how will it get to the flash line after the redirect? Though I may be missing what redirect_back_or_default is supposed to do.

Calls to redirect, render etc. don’t terminate the action so there’s nothing very wrong about this (don’t know if the rails 3.1 changes to flushing will change this)

rescue ActiveRecord::RecordInvalid

More odd looking code, or did the syntax for rescue change dramatically with Rails 2 from Rails 1

That’s just standard ruby.

Fred

I thought you had to have begin ... rescue ... end

Colin

I changed the order of my "def signup" as follows:

class UserController < ApplicationController

public   def signup     return unless request.post?     @user = User.new(@params[:user])     @user.save!     redirect_back_or_default(:controller => 'grapher', :action => 'index')     flash[:notice] = "New User Successfully Created"     rescue ActiveRecord::RecordInvalid     render :action => 'signup'    end

.. and now my form page comes up but still get this error message when I hit submit:

NoMethodError in UserController#signup You have a nil object when you didn't expect it! You might have expected an instance of ActiveRecord::Base. The error occurred while evaluating nil.

thanks jack

It should be params[..] not @params[..]

I thought you said the code worked before you upgraded.

I also suggest you have a look at the Rails Guide on debugging (and the other guides in fact). That will show you how to use ruby-debug to break into the code and inspect the data. In this case, for example, you could have broken in before the @user= line and you would see that @params was nil, which would have made you look more closely at it and realise the typo.

Colin

def some_method ... rescue ... end

works too

Fred

Once again the trivial extent of my knowledge is exposed :slight_smile: No doubt that is documented somewhere in the Ruby docs, but it did not leap out at me from anywhere I looked.

Thanks

Colin