Working through the beginning phase from the Agile book on ''Administration'' undefined method `hashed_password='' for #<User:0xb7911324> ... /usr/lib/ruby/gems/1.8/gems/activerecord-1.13.2/lib/active_record/base.rb:1498:in `method_missing'' #{RAILS_ROOT}/app/models/user.rb:12:in `before_create'' ./script/../config/../app/controllers/login_controller.rb:8:in `add_user'' ... Request Parameters: {"user"=>{"name"=>"Craig White", "login"=>"craig", "password"=>"test"}} OK... My user.rb includes... require "digest/sha1" class User < ActiveRecord::Base attr_accessor :password attr_accessible :login, :password, :name def before_create self.hashed_password = User.hash_password(self.password) end private def self.hash_password(password) Digest::SHA1.hexdigest(password) end end Where am I going wrong? Craig
Craig White wrote:> require "digest/sha1" > class User < ActiveRecord::Base > > attr_accessor :password > attr_accessible :login, :password, :name > > def before_create > self.hashed_password = User.hash_password(self.password) > end > > private > > def self.hash_password(password) > Digest::SHA1.hexdigest(password) > end > end > > Where am I going wrong? > > CraigTry remove the ''private'', see what happens. Joey -- Posted via http://www.ruby-forum.com/.
Try this in your before_create() method: @hashed_password = User.hash_password(password) This will create an instance variable for this User, named @hashed_password and populated with the SHA digested value of the password that was entered in the request. It looks to me like you are using "self" in Ruby as you would use "this" in Java, which is going to cause problems like this. They''re not equivalent. Hope this helps, David On Feb 15, 2006, at 10:28 AM, Craig White wrote:> require "digest/sha1" > class User < ActiveRecord::Base > > attr_accessor :password > attr_accessible :login, :password, :name > > def before_create > self.hashed_password = User.hash_password(self.password) > end > > private > > def self.hash_password(password) > Digest::SHA1.hexdigest(password) > end > end > > Where am I going wrong?-------------- next part -------------- An HTML attachment was scrubbed... URL: http://wrath.rubyonrails.org/pipermail/rails/attachments/20060215/b3fc84c7/attachment.html
That get''s me past the error but then the password column is written as null to the db which obviously isn''t the expected behavior. I believe the intent is to take the :password and hash it just prior to writing it to db so putting the hash into an instance variable would require another assignment back...which I will play with but it seems like an extra step which I think was the author''s intention of using ''self''. I am taking this out of the book so I expected it to work. Thanks Craig On Wed, 2006-02-15 at 10:52 -0700, David Rupp wrote:> Try this in your before_create() method: > > > @hashed_password = User.hash_password(password) > > > This will create an instance variable for this User, named > @hashed_password and populated with the SHA digested value of the > password that was entered in the request. > > > It looks to me like you are using "self" in Ruby as you would use > "this" in Java, which is going to cause problems like this. They''re > not equivalent. > > > Hope this helps, > David > > On Feb 15, 2006, at 10:28 AM, Craig White wrote: > > > require "digest/sha1" > > > > class User < ActiveRecord::Base > > > > > > attr_accessor :password > > > > attr_accessible :login, :password, :name > > > > > > def before_create > > > > self.hashed_password = User.hash_password(self.password) > > > > end > > > > > > private > > > > > > def self.hash_password(password) > > > > Digest::SHA1.hexdigest(password) > > > > end > > > > end > > > > > > Where am I going wrong? > > > > > _______________________________________________ > Rails mailing list > Rails@lists.rubyonrails.org > http://lists.rubyonrails.org/mailman/listinfo/rails
On Wed, 2006-02-15 at 18:44 +0100, joey__ wrote:> Craig White wrote: > > > require "digest/sha1" > > class User < ActiveRecord::Base > > > > attr_accessor :password > > attr_accessible :login, :password, :name > > > > def before_create > > self.hashed_password = User.hash_password(self.password) > > end > > > > private > > > > def self.hash_password(password) > > Digest::SHA1.hexdigest(password) > > end > > end > > > > Where am I going wrong? > > > > Craig > > Try remove the ''private'', see what happens.---- I tried that before I posted to list...didn''t change anything. I have tried a lot of stuff - getting stuck following a book is frustrating. Thanks Craig
Hmm. Does your users table have a column named "hashed_password"? Your model should automatically know about all the columns in its corresponding table (User -> users, in your case). If your users table doesn''t have this column, you should add it and restart your server. If it *does* have the column, you may still need to restart your server (to pick up the most recent version of the database). David On Feb 15, 2006, at 10:28 AM, Craig White wrote:> Working through the beginning phase from the Agile book on > ''Administration'' > > undefined method `hashed_password='' for #<User:0xb7911324> > ... > /usr/lib/ruby/gems/1.8/gems/activerecord-1.13.2/lib/active_record/ > base.rb:1498:in `method_missing'' > #{RAILS_ROOT}/app/models/user.rb:12:in `before_create'' > ./script/../config/../app/controllers/login_controller.rb:8:in > `add_user'' > ... > Request > Parameters: {"user"=>{"name"=>"Craig White", "login"=>"craig", > "password"=>"test"}} > > OK... > > My user.rb includes... > > require "digest/sha1" > class User < ActiveRecord::Base > > attr_accessor :password > attr_accessible :login, :password, :name > > def before_create > self.hashed_password = User.hash_password(self.password) > end > > private > > def self.hash_password(password) > Digest::SHA1.hexdigest(password) > end > end > > Where am I going wrong? > > Craig > > _______________________________________________ > Rails mailing list > Rails@lists.rubyonrails.org > http://lists.rubyonrails.org/mailman/listinfo/rails
Craig: I''ve used that code in three separate applications... I know it works. I''ve made some minor changes to this code which I will send to you so you can try it out. Assuming your table is: ActiveRecord::Schema.define() do create_table "users", :force => true do |t| t.column "username", :string, :limit => 100, :default => "", :null => false t.column "hashed_password", :string, :default => "", :null => false end end Or something along those lines, then the Agile book''s code should work just fine. You are correct: You should *not* have a password field in your database. The "password" is only used to hold the clear-text password until it is hashed. (self.hashed_password User.hash_password(self.password)) --user.rb ---- require "digest/sha1" class User < ActiveRecord::Base attr_accessor :password validates_uniqueness_of :username validates_presence_of :username def validate_on_create if self.password == "" or self.password.nil? errors.add_to_base("Password field must not be left blank!") end end # hash the password for storage in the DB def before_create self.hashed_password = User.hash_password(self.password) end # hash the password before updating but only if the password field is actually # filled in. This helps to prevent changing the password accidentally on an update. def before_update() unless self.password.nil? self.password = User.hash_password(self.password) end end def after_create self.password = nil end # This exists so that you can easily create a "user" by # simply passing the form params to this object and "try to login" # on that object. It''s just to reduce code. def try_to_login User.login(self.username, self.password) end private def self.hash_password(password) Digest::SHA1.hexdigest(password) end # Receives a username and password def self.login(username, password) hashed_password = hash_password(password || "") find(:first, :conditions => ["username = ? and hashed_password = ?", username, hashed_password]) end End ---/user.rb-------- I hope this helps you get moving a bit more. -Brian -----Original Message----- From: rails-bounces@lists.rubyonrails.org [mailto:rails-bounces@lists.rubyonrails.org] On Behalf Of Craig White Sent: Wednesday, February 15, 2006 12:45 PM To: rails@lists.rubyonrails.org Subject: Re: [Rails] Agile book - getting confusing error That get''s me past the error but then the password column is written as null to the db which obviously isn''t the expected behavior. I believe the intent is to take the :password and hash it just prior to writing it to db so putting the hash into an instance variable would require another assignment back...which I will play with but it seems like an extra step which I think was the author''s intention of using ''self''. I am taking this out of the book so I expected it to work. Thanks Craig On Wed, 2006-02-15 at 10:52 -0700, David Rupp wrote:> Try this in your before_create() method: > > > @hashed_password = User.hash_password(password) > > > This will create an instance variable for this User, named > @hashed_password and populated with the SHA digested value of the > password that was entered in the request. > > > It looks to me like you are using "self" in Ruby as you would use > "this" in Java, which is going to cause problems like this. They''re > not equivalent. > > > Hope this helps, > David > > On Feb 15, 2006, at 10:28 AM, Craig White wrote: > > > require "digest/sha1" > > > > class User < ActiveRecord::Base > > > > > > attr_accessor :password > > > > attr_accessible :login, :password, :name > > > > > > def before_create > > > > self.hashed_password = User.hash_password(self.password) > > > > end > > > > > > private > > > > > > def self.hash_password(password) > > > > Digest::SHA1.hexdigest(password) > > > > end > > > > end > > > > > > Where am I going wrong? > > > > > _______________________________________________ > Rails mailing list > Rails@lists.rubyonrails.org > http://lists.rubyonrails.org/mailman/listinfo/rails_______________________________________________ Rails mailing list Rails@lists.rubyonrails.org http://lists.rubyonrails.org/mailman/listinfo/rails
I am so dumb...thanks column was called ''password'' and not ''hashed_password'' thanks Craig On Wed, 2006-02-15 at 12:00 -0700, David Rupp wrote:> Hmm. Does your users table have a column named "hashed_password"? > Your model should automatically know about all the columns in its > corresponding table (User -> users, in your case). > > If your users table doesn''t have this column, you should add it and > restart your server. If it *does* have the column, you may still need > to restart your server (to pick up the most recent version of the > database). > > David > > On Feb 15, 2006, at 10:28 AM, Craig White wrote: > > > Working through the beginning phase from the Agile book on > > ''Administration'' > > > > undefined method `hashed_password='' for #<User:0xb7911324> > > ... > > /usr/lib/ruby/gems/1.8/gems/activerecord-1.13.2/lib/active_record/ > > base.rb:1498:in `method_missing'' > > #{RAILS_ROOT}/app/models/user.rb:12:in `before_create'' > > ./script/../config/../app/controllers/login_controller.rb:8:in > > `add_user'' > > ... > > Request > > Parameters: {"user"=>{"name"=>"Craig White", "login"=>"craig", > > "password"=>"test"}} > > > > OK... > > > > My user.rb includes... > > > > require "digest/sha1" > > class User < ActiveRecord::Base > > > > attr_accessor :password > > attr_accessible :login, :password, :name > > > > def before_create > > self.hashed_password = User.hash_password(self.password) > > end > > > > private > > > > def self.hash_password(password) > > Digest::SHA1.hexdigest(password) > > end > > end > > > > Where am I going wrong? > > > > Craig > > > > _______________________________________________ > > Rails mailing list > > Rails@lists.rubyonrails.org > > http://lists.rubyonrails.org/mailman/listinfo/rails > > _______________________________________________ > Rails mailing list > Rails@lists.rubyonrails.org > http://lists.rubyonrails.org/mailman/listinfo/rails
Yeah...I blew it on the table...cuz I was looking at Chad''s ''Recipes'' and at Agile book and trying to work out the issues. Chad''s ''Recipes'' threw me for a loop because it ''require "digest/md5" which turns out that I don''t have that installed - had to figure it out from script/console and so I punted back to Agile book which uses "digest/sha1" which is installed at which point the postgres table was already created with a ''password'' column and Agile book clearly uses ''hashed_password'' as the column. *** Doh *** Thanks Craig PS...I''m not interested at this point in adding digest/md5 On Wed, 2006-02-15 at 13:04 -0600, Hogan, Brian P. wrote:> Craig: > I''ve used that code in three separate applications... I know it works. > I''ve made some minor changes to this code which I will send to you so > you can try it out. > > Assuming your table is: > > ActiveRecord::Schema.define() do > create_table "users", :force => true do |t| > t.column "username", :string, :limit => 100, :default => "", :null > => false > t.column "hashed_password", :string, :default => "", :null => false > end > end > > Or something along those lines, then the Agile book''s code should work > just fine. > You are correct: You should *not* have a password field in your > database. The "password" is only used to hold the clear-text password > until it is hashed. (self.hashed_password > User.hash_password(self.password)) > > --user.rb ---- > > require "digest/sha1" > class User < ActiveRecord::Base > attr_accessor :password > validates_uniqueness_of :username > validates_presence_of :username > > def validate_on_create > if self.password == "" or self.password.nil? > errors.add_to_base("Password field must not be left blank!") > end > end > > # hash the password for storage in the DB > def before_create > self.hashed_password = User.hash_password(self.password) > end > > # hash the password before updating but only if the password field is > actually > # filled in. This helps to prevent changing the password accidentally > on an update. > def before_update() > unless self.password.nil? > self.password = User.hash_password(self.password) > end > end > > def after_create > self.password = nil > end > > # This exists so that you can easily create a "user" by > # simply passing the form params to this object and "try to login" > # on that object. It''s just to reduce code. > def try_to_login > User.login(self.username, self.password) > end > > private > def self.hash_password(password) > Digest::SHA1.hexdigest(password) > end > > # Receives a username and password > def self.login(username, password) > hashed_password = hash_password(password || "") > find(:first, > :conditions => ["username = ? and hashed_password = ?", > username, hashed_password]) > end > End > > ---/user.rb-------- > > I hope this helps you get moving a bit more. > > -Brian > > > -----Original Message----- > From: rails-bounces@lists.rubyonrails.org > [mailto:rails-bounces@lists.rubyonrails.org] On Behalf Of Craig White > Sent: Wednesday, February 15, 2006 12:45 PM > To: rails@lists.rubyonrails.org > Subject: Re: [Rails] Agile book - getting confusing error > > > That get''s me past the error but then the password column is written as > null to the db which obviously isn''t the expected behavior. I believe > the intent is to take the :password and hash it just prior to writing it > to db so putting the hash into an instance variable would require > another assignment back...which I will play with but it seems like an > extra step which I think was the author''s intention of using ''self''. > > I am taking this out of the book so I expected it to work. > > Thanks > > Craig > > On Wed, 2006-02-15 at 10:52 -0700, David Rupp wrote: > > Try this in your before_create() method: > > > > > > @hashed_password = User.hash_password(password) > > > > > > This will create an instance variable for this User, named > > @hashed_password and populated with the SHA digested value of the > > password that was entered in the request. > > > > > > It looks to me like you are using "self" in Ruby as you would use > > "this" in Java, which is going to cause problems like this. They''re > > not equivalent. > > > > > > Hope this helps, > > David > > > > On Feb 15, 2006, at 10:28 AM, Craig White wrote: > > > > > require "digest/sha1" > > > > > > class User < ActiveRecord::Base > > > > > > > > > attr_accessor :password > > > > > > attr_accessible :login, :password, :name > > > > > > > > > def before_create > > > > > > self.hashed_password = User.hash_password(self.password) > > > > > > end > > > > > > > > > private > > > > > > > > > def self.hash_password(password) > > > > > > Digest::SHA1.hexdigest(password) > > > > > > end > > > > > > end > > > > > > > > > Where am I going wrong? > > > > > > > > > _______________________________________________ > > Rails mailing list > > Rails@lists.rubyonrails.org > > http://lists.rubyonrails.org/mailman/listinfo/rails > > _______________________________________________ > Rails mailing list > Rails@lists.rubyonrails.org > http://lists.rubyonrails.org/mailman/listinfo/rails > _______________________________________________ > Rails mailing list > Rails@lists.rubyonrails.org > http://lists.rubyonrails.org/mailman/listinfo/rails