Same name action and attribute in a model

I have been following following tutorial to make a user login session.
http://www.aidanf.net/rails_user_authentication_tutorial

I used the following action to encrypt the password.

def password
#debugger
@password1=pass
self.salt = SecureRandom.hex(10) if !self.salt?
self.password = User.encrypt(@password1, self.salt)
end

but when it is called following error is generated.

SystemStackError (stack level too deep):

app/models/user.rb:26:in password=' app/models/user.rb:27:in password=’
app/controllers/user_controller.rb:31:in new' app/controllers/user_controller.rb:31:in createuser’

I am not sure if this way of calling an action is correct or not. I need
help with this one asap.

On 27 July 2012 07:22, Sumit S. [email protected]
wrote:

end

but when it is called following error is generated.

SystemStackError (stack level too deep):
app/models/user.rb:26:in password=' app/models/user.rb:27:in password=’
app/controllers/user_controller.rb:31:in new' app/controllers/user_controller.rb:31:in createuser’

Which (if any) of those lines is line 26 in your UserController? What
does the User.encrypt method look like?

On 27 July 2012 08:07, Michael P. [email protected] wrote:

Which (if any) of those lines is line 26 in your UserController? What
does the User.encrypt method look like?

Ignore me… I can’t even read your error message properly myself.

I used the following action to encrypt the password.

def password
#debugger
@password1=pass
self.salt = SecureRandom.hex(10) if !self.salt?
self.password = User.encrypt(@password1, self.salt)
end

Right… so where does the value of “pass” come from? Is there a
method that returns it?

In the (six year old) tutorial you’re following, the method is:

def password=(pass)
@password=pass
self.salt = User.random_string(10) if !self.salt?
self.hashed_password = User.encrypt(@password, self.salt)
end

but you’ve changed it to not take any attributes, and to update
“self.password” rather than “self.hashed_password”. It would probably
help a little to post a bit more (all) of your model. Also, I’m
curious why, if you’re following a tutorial, would you change large
chunks of the functionality? If you implement it exactly as described,
does it work?

This is the complete model. I am trying to encrypt the password.

require ‘digest/sha1’

def passwordtext=(pass)

Regards
Sumit S.

The power of imagination makes us infinite…

I am not exactly following the tutorial. I have customized things
according
to my requirements.

Regards
Sumit S.

The power of imagination makes us infinite…

The self.hashedpass action is still not in use. That is not of concern
right now. I need to encrypt the password chosen by user and save it. In
this tutorial, it sets an attr_accessor “password” which executes the
instance method *“password=(pass)”. *The tutorial actually uses
*hashes_password
*as the attribute in table where the encrypted password is actually
stored
after encryption.

During customizations I have used password as the column where
encrypted
password shall be saved. So I created my own attr_accessor, i.e., *
passwordtext
. I have named the password_field_tag in my form as *
passwordtext
. But when I do so, it is not executed. Instead if I rename
the password_field_tag and the attr_accessor as* password *only, it is
executed but the stackerror comes in.

Regards
Sumit S.

The power of imagination makes us infinite…

On 27 July 2012 10:42, sumit srivastava [email protected]
wrote:

This is the complete model. I am trying to encrypt the password.

def self.hashedpass(login, pass)
u=find(:first, :conditions=>[“login = ?”, login])
return nil if u.nil?
return u if User.encrypt(pass, u.salt)==u.hashed_password
nil
end

You compare the hashed user input with the u.hashed_password attribute
here…

def passwordtext=(pass)
#debugger
@password1=pass
self.salt = SecureRandom.hex(10) if !self.salt?
self.password = User.encrypt(@password1, self.salt)
end

…but here you’re setting the “password” attribute - so is there a
“hashed_password” attribute on the user? And if so, how is it set?

I am not exactly following the tutorial. I have customized things according to
my requirements.

Your requirement was to have a non-working password hashing process?!

  • as it seems that’s all your customization has achieved.
    What was wrong with the tutorial that didn’t work for you?

This is what I receive,

SystemStackError (stack level too deep):
app/models/user.rb:26:in password=' app/models/user.rb:27:inpassword=’
app/controllers/user_controller.rb:31:in new' app/controllers/user_controller.rb:31:increateuser’

Here createuser action is used to store the user info into database.

Line 31 reads as follows,*
@user = User.new(params[:user])*

Regards
Sumit S.

The power of imagination makes us infinite…

User.random_string does not exists any more. So had to use *
SecureRandom.hex(10)*

On 27 July 2012 11:13, sumit srivastava [email protected]
wrote:

During customizations I have used password as the column where encrypted
password shall be saved. So I created my own attr_accessor, i.e.,
passwordtext. I have named the password_field_tag in my form as
passwordtext. But when I do so, it is not executed. Instead if I rename the
password_field_tag and the attr_accessor as password only, it is executed
but the stackerror comes in.

All of this info would have been very helpful in your OP… anyway…

… what happens when you try this:

def passwordtext=(pass)
@passwordtext=pass
self.salt = User.random_string(10) if !self.salt?
self.password = User.encrypt(@passwordtext, self.salt)
end

If it’s still overflowing, can you post the error message again (since
the model has changed since your first post this morning) and the
corresponding method from the controller, as it might be something in
there behaving weirdly.

On 27 July 2012 11:37, sumit srivastava [email protected]
wrote:

Line 31 reads as follows,
@user = User.new(params[:user])

I would put a breakpoint on that line and then keep stepping into
until you see where it’s looping :-/

I’m using

before_save :encrypt_password

def encrypt_password
unless password.blank?
self.password_digest = BCrypt::Password.create(password)
self.password = nil
self.password_confirmation = nil
end
end

tom

On Jul 27, 2012, at 12:30 , Michael P. [email protected] wrote:

… what happens when you try this:
there behaving weirdly.


You received this message because you are subscribed to the Google G. “Ruby
on Rails: Talk” group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to
[email protected].
For more options, visit https://groups.google.com/groups/opt_out.

Tomas Meinlschmidt, MS {MCT, MCP+I, MCSE, AER}, NetApp Filer/NetCache

www.meinlschmidt.com www.maxwellrender.cz www.lightgems.cz

Pavling,

I removed the line
*self.password = User.encrypt(@password1, self.salt)

*and rest worked fine. So I deduced that this might be calling password
action again and going into recursive action. That’s the reason I
changed
my variables as explained earlier…

Tom,
That might be another solution. But what I am trying to know is why
isn’t
this method working. And how is the action *def password=(pass)
*actually
being called. Because I didn’t see any exclusive line where it is being
called. My analysis says it is being executed because of the
attr_accessorand having name same as that of the column
*password.

Am I right?

*Regards
Sumit S.

The power of imagination makes us infinite…

Right now I have renamed it to passwordtext but originally it was
password.
I wrote about its behavior when named as password.

Regards
Sumit S.

The power of imagination makes us infinite…

On 27 July 2012 17:31, sumit srivastava [email protected]
wrote:

Right now I have renamed it to passwordtext but originally it was password.
I wrote about its behavior when named as password.

Okay… so what help is that? What difference does what something
used to be make?! If you have a problem now it’s only a concern
what the settings are now.

Have you followed through in the debugger to see what’s going on?

On 27 July 2012 11:52, sumit srivastava [email protected]
wrote:

That might be another solution. But what I am trying to know is why isn’t
this method working. And how is the action def password=(pass) actually
being called. Because I didn’t see any exclusive line where it is being
called. My analysis says it is being executed because of the attr_accessor
and having name same as that of the column password.

Which accessor? The only accessor you have is passwordtext.

On Friday, July 27, 2012 11:52:26 AM UTC+1, Sumit S. wrote:

Tom,
That might be another solution. But what I am trying to know is why isn’t
this method working. And how is the action *def password=(pass) actually
being called. Because I didn’t see any exclusive line where it is being
called. My analysis says it is being executed because of the *
attr_accessor
and having name same as that of the column *password.

*Am I right?

It’s hard to say because it’s extremely hard to piece together what code
exactly is excuting - seems like there’s at least 3 different versions
in
this thread, but it sounds to me like you’ve
definte a password= method always calls self.password= which (by
definition) calls your password= method and so you end up in an infinite
recursion.
The original tutorial you followed used a different name for the
attribute
so instead of calling self.password they were calling
self.hashed_password=
instead. You could either follow the tutorial (although as others have
pointed it, it is really old (Rails 3.2has a has_secure_password that
handles this) or use self.write_attribute(:password, some_value) when
you
want to store the hashed value

Fred

Let me make it clear what exactly I have tried.

The original article contains following code,

def password=(pass)

@password=pass
self.salt = User.random_string(10) if !self.salt?
self.hashed_password = User.encrypt(@password, self.salt)

end

Since I have password as the field in database to save my password, I
changed hashed_password to password

def password=(pass)
@password1=pass
self.salt = SecureRandom.hex(10) if !self.salt?
self.password = User.encrypt(@password1, self.salt)
end

This gave me the error,

SystemStackError (stack level too deep):

app/models/user.rb:26:in password=' app/models/user.rb:27:inpassword=’
app/controllers/user_controlle
r.rb:31:in new' app/controllers/user_controller.rb:31:increateuser’

So I updated the method as follows,

def passwordtext=(pass)

@password1=pass
self.salt = SecureRandom.hex(10) if !self.salt?
self.password = User.encrypt(@password1, self.salt)
end

And added a attr_accessor named as passwordtext. Also I renamed the
password_field_tag in the view as “passwordtext”. Doing this didn’t help
at
all as the passwordtext method didn’t execute.

So, the problem how should I rename my variables to make it work.

Regards
Sumit S.

The power of imagination makes us infinite…

By “didn’t execute”, I mean that when I use “password” as name of this
method, it is called some way. But the same doesn’t happens when it is
named as “passwordtext”, i.e., it is not even called.

Regards
Sumit S.

The power of imagination makes us infinite…

On Monday, July 30, 2012 6:16:47 AM UTC+1, Sumit S. wrote:

And added a attr_accessor named as passwordtext. Also I renamed the
password_field_tag in the view as “passwordtext”. Doing this didn’t help at
all as the passwordtext method didn’t execute.

So, the problem how should I rename my variables to make it work.

Not sure what you mean by ‘didn’t execute’ but the instance variable you
set should be @passwordtext if that’s the name you gave attr_accessor.
You
also want to make sure you passwordtext= method is defined after the
call
to attr_accessor

Fred