Same name action and attribute in a model

35 views
Skip to first unread message

Sumit Srivastava

unread,
Jul 27, 2012, 2:22:43 AM7/27/12
to rubyonra...@googlegroups.com
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.

Michael Pavling

unread,
Jul 27, 2012, 3:07:19 AM7/27/12
to rubyonra...@googlegroups.com
On 27 July 2012 07:22, Sumit Srivastava <sumit.the...@gmail.com> wrote:
> 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'

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

Michael Pavling

unread,
Jul 27, 2012, 3:16:56 AM7/27/12
to rubyonra...@googlegroups.com
On 27 July 2012 08:07, Michael Pavling <pav...@gmail.com> 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?

sumit srivastava

unread,
Jul 27, 2012, 5:42:40 AM7/27/12
to rubyonra...@googlegroups.com
This is the complete model. I am trying to encrypt the password.


require 'digest/sha1'

class User < ActiveRecord::Base
  attr_accessible :mailid, :name, :password, :username
      validates:name, :presence=>true
    validates:mailid, :presence=>true
      validates:username, :presence=>true
      validates:password, :presence=>true
      validates_uniqueness_of :username, :mailid
      validates_format_of :mailid, :with => /^([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})$/i, :message => "Invalid email" 
     
      attr_accessor :passwordtext
  has_many :contacts
 
  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 
 
  def passwordtext=(pass)

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


Regards
Sumit Srivastava

The power of imagination makes us infinite...



--
You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group.
To post to this group, send email to rubyonra...@googlegroups.com.
To unsubscribe from this group, send email to rubyonrails-ta...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.



sumit srivastava

unread,
Jul 27, 2012, 5:44:07 AM7/27/12
to rubyonra...@googlegroups.com
I am not exactly following the tutorial. I have customized things according to my requirements.


Regards
Sumit Srivastava

The power of imagination makes us infinite...


Michael Pavling

unread,
Jul 27, 2012, 5:58:50 AM7/27/12
to rubyonra...@googlegroups.com
On 27 July 2012 10:42, sumit srivastava <sumit.the...@gmail.com> 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?

sumit srivastava

unread,
Jul 27, 2012, 6:13:32 AM7/27/12
to rubyonra...@googlegroups.com
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 Srivastava

The power of imagination makes us infinite...


Michael Pavling

unread,
Jul 27, 2012, 6:30:42 AM7/27/12
to rubyonra...@googlegroups.com
On 27 July 2012 11:13, sumit srivastava <sumit.the...@gmail.com> 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.

sumit srivastava

unread,
Jul 27, 2012, 6:37:40 AM7/27/12
to rubyonra...@googlegroups.com
This is what I receive,


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'

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

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


Regards
Sumit Srivastava

The power of imagination makes us infinite...


Sumit Srivastava

unread,
Jul 27, 2012, 6:40:06 AM7/27/12
to rubyonra...@googlegroups.com
User.random_string does not exists any more. So had to use SecureRandom.hex(10)

Tom Meinlschmidt

unread,
Jul 27, 2012, 6:39:35 AM7/27/12
to rubyonra...@googlegroups.com

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
> --
> You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group.
> To post to this group, send email to rubyonra...@googlegroups.com.
> To unsubscribe from this group, send email to rubyonrails-ta...@googlegroups.com.
> 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
===============================================================================

Michael Pavling

unread,
Jul 27, 2012, 6:42:34 AM7/27/12
to rubyonra...@googlegroups.com
On 27 July 2012 11:37, sumit srivastava <sumit.the...@gmail.com> wrote:
> This is what I receive,
>
> 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'
>
> Here createuser action is used to store the user info into database.
>
> 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 :-/

sumit srivastava

unread,
Jul 27, 2012, 6:52:26 AM7/27/12
to rubyonra...@googlegroups.com
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_accessor and having name same as that of the column password.

Am I right?

Regards
Sumit Srivastava

The power of imagination makes us infinite...


Michael Pavling

unread,
Jul 27, 2012, 10:09:29 AM7/27/12
to rubyonra...@googlegroups.com
On 27 July 2012 11:52, sumit srivastava <sumit.the...@gmail.com> 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.

sumit srivastava

unread,
Jul 27, 2012, 12:31:57 PM7/27/12
to rubyonra...@googlegroups.com
Right now I have renamed it to passwordtext but originally it was password. I wrote about its behavior when named as password.

Regards
Sumit Srivastava

The power of imagination makes us infinite...


Michael Pavling

unread,
Jul 27, 2012, 1:24:57 PM7/27/12
to rubyonra...@googlegroups.com
On 27 July 2012 17:31, sumit srivastava <sumit.the...@gmail.com> 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?

Frederick Cheung

unread,
Jul 29, 2012, 5:17:45 AM7/29/12
to rubyonra...@googlegroups.com


On Friday, July 27, 2012 11:52:26 AM UTC+1, Sumit Srivastava 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
 
Regards
Sumit Srivastava

The power of imagination makes us infinite...


On 27 July 2012 16:12, Michael Pavling <pav...@gmail.com> wrote:
On 27 July 2012 11:37, sumit srivastava <sumit.the...@gmail.com> wrote:
> This is what I receive,
>
> 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'
>
> Here createuser action is used to store the user info into database.
>
> 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 :-/

--
You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group.
To post to this group, send email to rubyonrails-talk@googlegroups.com.
To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe@googlegroups.com.

sumit srivastava

unread,
Jul 30, 2012, 1:16:47 AM7/30/12
to rubyonra...@googlegroups.com
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:in `password='
>   app/controllers/user_controlle
r.rb:31:in `new'
>   app/controllers/user_controller.rb:31:in `createuser'
>

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 Srivastava

The power of imagination makes us infinite...


To post to this group, send email to rubyonra...@googlegroups.com.
To unsubscribe from this group, send email to rubyonrails-ta...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msg/rubyonrails-talk/-/Ed2oQol364oJ.

Frederick Cheung

unread,
Jul 30, 2012, 8:11:44 AM7/30/12
to rubyonra...@googlegroups.com
On Monday, July 30, 2012 6:16:47 AM UTC+1, Sumit Srivastava wrote:
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.


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
 

sumit srivastava

unread,
Jul 30, 2012, 8:47:16 AM7/30/12
to rubyonra...@googlegroups.com
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 Srivastava

The power of imagination makes us infinite...


To post to this group, send email to rubyonra...@googlegroups.com.
To unsubscribe from this group, send email to rubyonrails-ta...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msg/rubyonrails-talk/-/ciXDKwGTLKQJ.
Reply all
Reply to author
Forward
0 new messages