So this has been a day of bug tracking.
I use a very simple authentication process for a site that I am writing in Rails 2.0. Here is the def in my model.
#Original def
def self.authenticate(user_info)
user = find_by_username(user_info[:username])
if user.username == user_info[:username] && user.hashed_password == hashed(user_info[:password])
return user
end
end
This may look familiar to some out there if you read the same materials that I read for pre-Rails 2 literature. While trying to get all of my login stuff working with Rails 2 this creates a …
You have a nil object when you didn’t expect it!
The error occurred while evaluating nil.username
This was a royal pain in the butt to fix but here is a work-around. I am not sure how viable it is as a solution, but I do know that it fixed my problem and now I can move on to the rest of the site without this thing hanging over my head.
Apparently in Rails 2.0 the way functions are called work differently than in Rails 1. I needed to use a different query to accomplish the same task. However, this particular query returns an array. So after you check the length of the recordset ( no [0] ) then you have to use the array ( with [0] ) to work with the results. Crazy thing is that when the results are returned to the controller, the need for the array disappears.
#work around def
def self.authenticate(user_info)
#get user using find instead of find_by_username
user = User.find(:all, :conditions => ["username = ?", user_info[:username]] )
#to check length of object you don’t need [0]
if user.length > 0
#to use the object you do need the [0]
if user[0].username == user_info[:username] && user[0].hashed_password == hashed(user_info[:password])
#when the result gets back to the controller the [0] will not need to be used
return user[0]
end
end
end
Let me know if you have a better solution for the work around.
You have a nil object when you didn’t expect it!
The error occurred while evaluating nil.username
simply replace
if user.username == user_info[:username] && user.hashed_password == hashed(user_info[:password])
with
if user && user.username == user_info[:username] && user.hashed_password == hashed(user_info[:password])
By: na43251 on July 28, 2008
at 12:09 pm
Couldn’t you also just do this?
def self.authenticate(user_info)
find(:first, :conditions=>{:username=>user_info[:username],:hashed_password=>hashed(user_info[:password])})
end
By: Tim on October 17, 2008
at 11:33 am
I’m not sure but I would be happy to give it a try. Thanks for the tip.
By: tszao on October 17, 2008
at 1:52 pm
I’m not sure but I would be happy to give it a try. Thanks for the tip.
By: tszao on October 17, 2008
at 1:53 pm