Instance variable not holding between get? and post

I am having trouble with this bit of code

if request.get?
session[:user_id] = nil
@user = User.new

  logger.error("get:#{@user.object_id}")
else
  logger.error("post:#{@user.object_id}")

  logged_in_user = @user.try_to_login

  if logged_in_user
    session[:user] = logged_in_user.id
    redirect_to(:action => "index")
  else
    flash[:notice] = "Invalid user/password combo"
  end

For some reason, when posting back the object_id of the @user variable
is 4 but when the get? is executed, the object_id is 28208630.

The error message is

NoMethodError (You have a nil object when you didn’t expect it!
The error occured while evaluating nil.try_to_login):

This happens if i enter a user name and password or leave them both
blank, and yes there is a method called try_to_login. Im trying to learn
rails and the code is exactly as is written in the book. Could something
have changed in rails since the book was published?

Hey Flipper -

Which book?

When you get to the line:

logged_in_user = @user.try_to_login

on the postback, you have not yet defined @user, thus the
“nil.try_to_login” error. Somewhere before that line you need to create
the @user instance variable as a new user object, probably by passing in
the parameters from the form, something like:

@user = User.new(params[:user])

Or even better, you don’t really need the @user object at that point, so
you could just do something like this:

logged_in_user = User.new(params[:user]).try_to_login

Check the code in your book again - they’ve got to be creating the @user
somewhere in the code before you get to that line. It doesn’t just come
back in fully-formed from the login view form without you doing anything
in the controller to create it.

c.

Flippper wrote:

I am having trouble with this bit of code

if request.get?
session[:user_id] = nil
@user = User.new

  logger.error("get:#{@user.object_id}")
else
  logger.error("post:#{@user.object_id}")

  logged_in_user = @user.try_to_login

  if logged_in_user
    session[:user] = logged_in_user.id
    redirect_to(:action => "index")
  else
    flash[:notice] = "Invalid user/password combo"
  end

For some reason, when posting back the object_id of the @user variable
is 4 but when the get? is executed, the object_id is 28208630.

The error message is

NoMethodError (You have a nil object when you didn’t expect it!
The error occured while evaluating nil.try_to_login):

This happens if i enter a user name and password or leave them both
blank, and yes there is a method called try_to_login. Im trying to learn
rails and the code is exactly as is written in the book. Could something
have changed in rails since the book was published?

Cayce B. wrote:

Hey Flipper -

Which book?

When you get to the line:

logged_in_user = @user.try_to_login

on the postback, you have not yet defined @user, thus the
“nil.try_to_login” error. Somewhere before that line you need to create
the @user instance variable as a new user object, probably by passing in
the parameters from the form, something like:

@user = User.new(params[:user])

Or even better, you don’t really need the @user object at that point, so
you could just do something like this:

logged_in_user = User.new(params[:user]).try_to_login

Check the code in your book again - they’ve got to be creating the @user
somewhere in the code before you get to that line. It doesn’t just come
back in fully-formed from the login view form without you doing anything
in the controller to create it.

c.

Thanks very much for that, it worked.

Although I dont understand why it needs to be reassigned.

Why would I @user = User.new in the get? and then recreate the User
object again at post?

The book mentioned that form data will be stored in the @user object so
woulden’t recreating it lose the information?

CatLady [] wrote:

Thanks very much for that, it worked.

Although I dont understand why it needs to be reassigned.

Why would I @user = User.new in the get? and then recreate the User
object again at post?

The book mentioned that form data will be stored in the @user object so
woulden’t recreating it lose the information?

I believe what you want is:

@user = User.new(params[:user])

This creates a new user object, but from the parameters passd in from
the form that just submitted it. The form doesn;t store the object
itself, just its attributes. And instance variables in controllers are
only alive for the length of a single request. Once a second request
comes in a new instane of the controller is created so all instance
variables are lost.

Because HTTP is a ‘stateless’ protocol. Between hitting the page for the
first time when rails does @user = User.new and the user submitting the
form with data, the server (and rails) completely ‘forgets’ what’s going
on. Each request, whether it is the first hit on the page (the GET) or
the submission of data (the POST), is a separate and distinct request to
the server. The server does not maintain any state data in between -
from its perspective, that @user variable is destroyed once the request
completes.

When the form is submitted, the data you filled in are part of the POST
header in the request. Rails picks this data out and populates the
params[] hash with it, giving you easy access to the data, but rails
really has no idea what kind of data that is or what you want to do with
it - that’s up to you. In this case, you have need of an object of a
particular class, so you create it. In other cases, maybe you just need
a particular piece of submitted data, so you’d access it in params[].

c.

Thanks very much for that, it worked.

Although I dont understand why it needs to be reassigned.

Why would I @user = User.new in the get? and then recreate the User
object again at post?

The book mentioned that form data will be stored in the @user object so
woulden’t recreating it lose the information?