Patrick McCafferty
2005-Aug-19 17:52 UTC
Can''t access a class method from a public method in Rails using the login_generator
I''m not sure if this is Rails-specific or if it''s a problem with my code in general, but I''ve hacked at it every which way and I can''t see why it''s failing the way it does. I wanted to change the salting method the logon generator used, so I tweaked the User#sha1 protected method to take both the username and password as arguments, and use part of the username in the salt, rather than the current method of a simple, constant salt. This worked perfectly, but I thought the style was slightly off, and so I moved the salt generation out into its own method, called salt_for, and just called sha1 with a salt retrieved from salt_for. For some reason this broke User#authenticate. No matter where I call salt_for, if authenticate is in the call stack it returns "undefined method", including if salt_for is called from User#sha1. The more curious bit of this is that salt_for CAN be accessed, directly, from the protected methods that hash the password to begin with. I only get the error from the authenticate method. Also curious is that User#sha1 is a protected method itself, so I don''t think I''m misunderstanding how method protection works in Ruby. If I just take the code out of salt_for and stick it in sha1, it''ll WORK, but elegance demands that it be a separate method. I''ve moved salt_for into the public section, as well, hoping that that was the issue: no dice. I''ve tried moving authenticate to the end of the class, thinking that maybe order of declaration mattered (even though authenticate is the first thing declared and sha1 is called from it); nothing. I''ve tried calling salt_for as self.salt_for and self.class.salt_for; none of it works. I don''t see where I''m going wrong here. Any help would be great. The error message it gives (with salt_for being called from sha1) is: NoMethodError in Account#login undefined method `salt_for'' for User:Class /app/models/user.rb:19:in `sha1'' /app/models/user.rb:59:in `authenticate'' app/controllers/account_controller.rb:7:in `login''