13

When I learn "Ruby on Rails Tutorial", and I want to create a User on console:

irb(main):001:0> User.create(name:"gsky",email:"k@q.com",
irb(main):002:1* password:"aaaaaa",password_confirmation:"aaaaaa")

then, I getting the following error message:

NoMethodError: undefined method cost' for BCrypt::Engine:Class
from D:/RailsInstaller/Ruby2.0.0/lib/ruby/gems/2.0.0/gems/activemodel-4.
0.2/lib/active_model/secure_password.rb:104:inpassword='
from D:/RailsInstaller/Ruby2.0.0/lib/ruby/gems/2.0.0/gems/activerecord-4
.0.2/lib/active_record/attribute_assignment.rb:42:in public_send'

This is user model:

class User < ActiveRecord::Base

  before_save { self.email = email.downcase }

  validates :name,  presence: true, length: { maximum: 50 }

  VALID_EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i

  validates :email, presence: true,
                    format: { with: VALID_EMAIL_REGEX },
                    uniqueness: { case_sensitive: false }

   has_secure_password

   validates :password, length: { minimum: 6 }

end
gotva
  • 5,919
  • 2
  • 25
  • 35
gsky
  • 193
  • 1
  • 10

5 Answers5

16

Add bcrypt-ruby to your Gemfile as specified below:

     gem 'bcrypt-ruby', '3.1.2'

then run bundle update from your project root directory and bundle install

osleonard
  • 595
  • 5
  • 22
  • Yeah, "gem 'bcrypt-ruby', '3.1.2' " in my Gemfile , but I getted the error message... – gsky Feb 18 '14 at 13:26
  • check you user.rb in your model folder if you have has_secure_password. if you have run rake db:migrate – osleonard Feb 18 '14 at 14:39
  • Yes, user.rb of my model have 'has_secure_password' ,and I runned rake db:migrate , it also throw:NoMethodError: undefined method `cost' for BCrypt::Engine:Class from D:/RailsInstaller/Ruby2.0.0/lib/ruby/gems/2.0.0/gems/activemodel-4.0.2/lib/active_model/secure_password.rb:104:in `password=' – gsky Feb 18 '14 at 14:48
  • please approve that you 1. run `bundle install` 2. restart your server/console after running bundle and migration – gotva Feb 18 '14 at 15:04
  • add ActiveModel::SecurePassword.min_cost = true to your test.rb at this path config/environments/test.rb then restart the server and test that should work – osleonard Feb 18 '14 at 17:33
  • oh, I am add ActiveModel::SecurePassword.min_cost = true to my test.rb at config/environments/test.rb ,but failed,it also throw:NoMethodError: undefined method cost' for BCrypt::Engine:Class from D:/RailsInstaller/Ruby2.0.0/lib/ruby/gems/2.0.0/gems/activemodel-4.0.2/lib/activ‌​e_model/secure_password.rb:104:in password=' – gsky Feb 18 '14 at 23:08
8

When i saw "Ruby On Rails Tutorial" I have met the same problem, I solved it by set Gemfile from:

gem 'bcrypt-ruby', '3.0.1' 

to:

gem 'bcrypt-ruby', '3.1.2' 

then run:

bundle install
qingxp9
  • 141
  • 1
  • 5
5

Also going for the tutorial/book and having the same problems, I used gem 'bcrypt-ruby', '~> 3.0.0' because of problems with bundle install. After going through secure_password.rb, the problem was in BCrypt::Engine.cost, this method actually doesn't exist.

I changed my gem to gem 'bcrypt-ruby', '~> 3.1.0' which installed bcrypt 3.1.7. Saw a warning message about the gem being renamed and changed it to gem 'bcrypt', '~> 3.1.0' (this part shouldn't matter). After doing bundle install, I was able to see the implementation of Bcrypt::Engine.cost through my IDE and I was able to make my user in rails c.

I want to add that adding ActiveModel::SecurePassword.min_cost = true in test.rb was able to let me make new users if I ran rails c in test environment, but when I added the same line in development.rb, it didn't work.

Cliche818
  • 51
  • 1
  • 2
  • when you have issues like that you should run bundle update which would update your gems that needed to automatically and secondly remove ActiveModel::SecurePassword.min_cost = true from you development.rb file as you do not need it. – osleonard May 06 '14 at 18:37
  • Worth pointing out that Rails test environment sets SecurePassword.min_cost to true which is why you see don't see this error when testing. Basically it's a mis-match between ActiveModel and bcrypt-ruby made undiscoverable in tests due to that switch. – toxaq Mar 02 '15 at 22:30
0

I think you are learning rails from the tutorial. If you just want to continue and not spent much time on doing the right fix, you can just use the cost as say 10, instead of calling the BCrypt::Engine.cost method.

So replace

cost = BCrypt::Engine.cost

with

cost = 10

This value when used will take less than 200ms to compute and that should be okay.

AbcAeffchen
  • 14,400
  • 15
  • 47
  • 66
0

Tested on mac:

Include this in your gemfile:

gem 'bcrypt', '3.1.11'

run:

xcode-select --install

then run: bundle install

That's it.

Best of lucks

Wilson
  • 71
  • 4