Undefined method IS defined in login subsystem

For some reason my login controller refuses to access a method i have
defined for another class. This is remedial stuff but my searches
haven’t cleared up the issue. It is creating the model but can’t access
the method. The method is NOT protected or private. Any thoughts? The
error:

undefined method `try_to_login’ for #Person:0x37ed3f0

LOGIN CONTROLLER:

class LoginController < ApplicationController

def login
#if a regular page load
if request.get?

  #destroy session info and create new person object
  session[:person_id] = nil
  @person = Person.new

else
  #create a new user object and fill it with entered form data
  @person = Person.new(params[:person])

  #take user object and 'try to log in' (see person model)
  logged_in_person = @person.try_to_login

  #if log in is successful
  if logged_in_person

    #set session id to user id and send home
    session[:id] = logged_in_person.id
    redirect_to :controller => 'room',
                :action => 'list'

  #otherwise complain
  else
      flash[:notice] = "Invalid email or password"
  end
end

end

PERSON MODEL:

class Person < ActiveRecord::Base

####################################
#LOGIN METHODS (see login controller)

def self.login(name, password)

#hash plaintext password entry
hashed_password = hash_password(password || "")

#return first user record matching entered name and converted 

password
find( :first,
:conditions => [“name = ? and hashed_password = ?”,
name, hashed_password])
end

def self.try_to_login
Person.login(self.name, self.password)
end

Hello Taylor,

For some reason my login controller refuses to access a method
i have defined for another class. This is remedial stuff but my
searches haven’t cleared up the issue. It is creating the model
but can’t access the method. The method is NOT protected or
private. Any thoughts? The error:

undefined method `try_to_login’ for #Person:0x37ed3f0

[…]

  #take user object and 'try to log in' (see person model)
  logged_in_person = @person.try_to_login

You’re calling #try_to_login as an instance method of @person instance.

[…]

class Person < ActiveRecord::Base
[…]
def self.try_to_login
Person.login(self.name, self.password)
end

You’ve defined #try_to_login as a class method. Furthermore
inside the #try_to_login code, self.name and self.password will
be calls to class methods Person#name and Person#password
and not instance methods.

So maybe you have to change #try_to_login to be an
instance method.

– Jean-François.


Ã? la renverse.

My understanding was that all class instances inherit all class methods.
‘Programming Ruby, 2nd Edition’ seems to validate this. Am I wrong?
How can I define an ‘instance method’ separate from the class? Thanks!

David,

I have your book! It is a great intro to ruby and it taught me a lot!
But obviously, not enough :frowning: Back to the question:

try_to_login is clearly a public instance method of Person. @person is
clearly an instance of Person. So why does @person.try_to_login fail
with ‘undefined method `try_to_login’ for #Person:0x37ed3f0?’

Hi –

On Sun, 29 Oct 2006, Taylor S. wrote:

My understanding was that all class instances inherit all class methods.
‘Programming Ruby, 2nd Edition’ seems to validate this. Am I wrong?
How can I define an ‘instance method’ separate from the class? Thanks!

class C
def m
end
end

m is an instance method. I’m not sure whether that addresses your
question, though. Can you expand a bit on the problem?

David


David A. Black | [email protected]
Author of “Ruby for Rails” [1] | Ruby/Rails training & consultancy [3]
DABlog (DAB’s Weblog) [2] | Co-director, Ruby Central, Inc. [4]
[1] Ruby for Rails | [3] http://www.rubypowerandlight.com
[2] http://dablog.rubypal.com | [4] http://www.rubycentral.org

David, I can assure you that my lack of proficiency has nothing to do
with your book and everything to do with my brain! Here is everything:

APPLICATION.RHTML

  <!--LOGIN / USER CP-->
  <div id="login">
    <% if session[:id] %>
      <%= render :partial => 'login/logged_in' %>
    <% else %>
      <%= render :partial => 'login/_login' %>
    <% end %>
    </div>

_LOGIN.RHTML

<%= form_tag(:controller => ‘Login’, :action => ‘login’) %>

Email <%= text_field 'person', 'email' %>

Password <%= password_field 'person', 'password' %>

<%= submit_tag "Login" %>

LOGIN CONTROLLER

class LoginController < ApplicationController

def login
#if a regular page load
if request.get?

  #destroy session info and create new person object
  session[:person_id] = nil
  @person = Person.new

else
  #create a new user object and fill it with entered form data
  @person = Person.new(params[:person])

  #take user object and 'try to log in' (see person model)
  logged_in_person = @person.try_to_login

  #if log in is successful
  if logged_in_person

    #set session id to user id and send home
    session[:id] = logged_in_person.id
    redirect_to :controller => 'room',
                :action => 'list'

  #otherwise complain
  else
      flash[:notice] = "Invalid email or password"
  end
end

end

PERSON MODEL

class Person < ActiveRecord::Base

####################################
#LOGIN METHODS (see login controller)

def self.login(name, password)

#hash plaintext password entry
hashed_password = hash_password(password || "")

#return first user record matching entered name and password
find( :first,
      :conditions => ["name = ? and hashed_password = ?",
                      name, hashed_password])

end

def self.try_to_login
Person.login(self.name, self.password)
end

Hi –

On Sun, 29 Oct 2006, Taylor S. wrote:

David,

I have your book! It is a great intro to ruby and it taught me a lot!

Thanks.

But obviously, not enough :frowning:

Whoops :slight_smile:

Back to the question:

try_to_login is clearly a public instance method of Person. @person is
clearly an instance of Person. So why does @person.try_to_login fail
with ‘undefined method `try_to_login’ for #Person:0x37ed3f0?’

You’ll need to show some code. There’s something going on that’s
impossible to pinpoint otherwise.

David


David A. Black | [email protected]
Author of “Ruby for Rails” [1] | Ruby/Rails training & consultancy [3]
DABlog (DAB’s Weblog) [2] | Co-director, Ruby Central, Inc. [4]
[1] Ruby for Rails | [3] http://www.rubypowerandlight.com
[2] http://dablog.rubypal.com | [4] http://www.rubycentral.org

Hello Taylor,

try_to_login is clearly a public instance method of Person.

No it isn’t. See your code :

class Person < ActiveRecord::Base

def self.try_to_login
Person.login(self.name, self.password)
end
end

@person is clearly an instance of Person.

Yes.

So why does @person.try_to_login fail with ‘undefined method
`try_to_login’ for #Person:0x37ed3f0?’

Because as I said earlier, you defined try_to_login as a class
method. If you don’t believe me, read again the chapter about
instance methods/class methods from David’s book :slight_smile:

– Jean-François.


À la renverse.

On 30/10/2006, at 4:10 AM, Taylor S. wrote:

try_to_login is clearly a public instance method of Person.
@person is
clearly an instance of Person. So why does @person.try_to_login fail
with ‘undefined method `try_to_login’ for #Person:0x37ed3f0?’

No, try_to_login is a public class method of Person. This is a class
method:

class Person
def self.blah

end
end

which you would call as Person.blah.

This is an instance method:

class Person
def blah

end
end

which you would call as:

person = Person.new
person.blah

You’re trying to call the try_to_login class method that you’ve
defined on an instance of Person, which doesn’t work.

Pete Y.
http://aliencamel.com/

Thanks this was all very helpful. Removing self. from self.try_to_login
fixed everything. And I learned about Class vs. instance variables.
Gracias!