Ruby on Rails: неопределенный метод 'digest' Учебное пособие по Rails, раздел 10.1.1

В настоящее время я просматриваю учебник по Rails от Майкла Хартла, и у меня возникла проблема в разделе 10.1.1, где я должен создать действие create_activation_digest в моей модели пользователя, которое создает и назначает токен активации и дайджест каждому пользователю при регистрации.

Сначала я сбросил свои миграции, используя:

bundle exec rake db:migrate:reset

А затем я посеял выборку пользователей в свою базу данных, используя:

bundle exec rake db:seed

Но я получаю сообщение об ошибке, в котором говорится:

NoMethodError: undefined method `digest' for #<Class:0x007fb23ae0dcd0>

Я предоставил полное сообщение об ошибке ниже.

Вот как выглядит мой файл user.rb:

class User < ActiveRecord::Base
    attr_accessor :remember_token, :activation_token
    before_save   :downcase_email
    before_create :create_activation_digest

    # Name Validations
    validates :name, presence: true, length: { maximum: 50 }

    # Email Validations
    VALID_EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i
    validates :email, presence: true, length: { maximum: 255 },
              format: { with: VALID_EMAIL_REGEX },
              uniqueness: { case_sensitive: false }

    # Password Validations
    has_secure_password
    validates :password, presence: true, length: { minimum: 6 }

    # Returns a random token
    def User.new_token
        SecureRandom.urlsafe_base64
    end

    # Remembers a user in the database for use in persistent sessions
    def remember
        self.remember_token = User.new_token
        update_attribute(:remember_digest, User.digest(remember_token))
    end

    # Returns true if the given token matches the digest
    def authenticated?(remember_token)
        return false if remember_digest.nil?
        BCrypt::Password.new(remember_digest).is_password?(remember_token)
    end

    # Forgets a user
    def forget
        update_attribute(:remember_digest, nil)
    end

    private
        # Converts email to all lower-case
        def downcase_email
            self.email = email.downcase
        end

        # Creates and assigns the activation token and digest
        def create_activation_digest
            self.activation_token  = User.new_token
            self.activation_digest = User.digest(activation_token)
        end


end

И вот сообщение об ошибке, которое я получаю в терминале:

0587343072:ruby_rails yuriramocan$ bundle exec rake db:seed --trace
** Invoke db:seed (first_time)
** Execute db:seed
** Invoke db:abort_if_pending_migrations (first_time)
** Invoke environment (first_time)
** Execute environment
** Execute db:abort_if_pending_migrations
rake aborted!
NoMethodError: undefined method `digest' for #<Class:0x007fb23ae0dcd0>
/Users/yuriramocan/.rvm/gems/ruby-2.2.2/gems/activerecord-4.2.3/lib/active_record/dynamic_matchers.rb:26:in `method_missing'
/Users/yuriramocan/Development/ruby_rails/app/models/user.rb:50:in `create_activation_digest'
/Users/yuriramocan/.rvm/gems/ruby-2.2.2/gems/activesupport-4.2.3/lib/active_support/callbacks.rb:430:in `block in make_lambda'
/Users/yuriramocan/.rvm/gems/ruby-2.2.2/gems/activesupport-4.2.3/lib/active_support/callbacks.rb:162:in `call'
/Users/yuriramocan/.rvm/gems/ruby-2.2.2/gems/activesupport-4.2.3/lib/active_support/callbacks.rb:162:in `block in halting'
/Users/yuriramocan/.rvm/gems/ruby-2.2.2/gems/activesupport-4.2.3/lib/active_support/callbacks.rb:502:in `call'
/Users/yuriramocan/.rvm/gems/ruby-2.2.2/gems/activesupport-4.2.3/lib/active_support/callbacks.rb:502:in `block in call'
/Users/yuriramocan/.rvm/gems/ruby-2.2.2/gems/activesupport-4.2.3/lib/active_support/callbacks.rb:502:in `each'
/Users/yuriramocan/.rvm/gems/ruby-2.2.2/gems/activesupport-4.2.3/lib/active_support/callbacks.rb:502:in `call'
/Users/yuriramocan/.rvm/gems/ruby-2.2.2/gems/activesupport-4.2.3/lib/active_support/callbacks.rb:88:in `run_callbacks'
/Users/yuriramocan/.rvm/gems/ruby-2.2.2/gems/activerecord-4.2.3/lib/active_record/callbacks.rb:306:in `_create_record'
/Users/yuriramocan/.rvm/gems/ruby-2.2.2/gems/activerecord-4.2.3/lib/active_record/timestamp.rb:57:in `_create_record'
/Users/yuriramocan/.rvm/gems/ruby-2.2.2/gems/activerecord-4.2.3/lib/active_record/persistence.rb:504:in `create_or_update'
/Users/yuriramocan/.rvm/gems/ruby-2.2.2/gems/activerecord-4.2.3/lib/active_record/callbacks.rb:302:in `block in create_or_update'
/Users/yuriramocan/.rvm/gems/ruby-2.2.2/gems/activesupport-4.2.3/lib/active_support/callbacks.rb:115:in `call'
/Users/yuriramocan/.rvm/gems/ruby-2.2.2/gems/activesupport-4.2.3/lib/active_support/callbacks.rb:115:in `call'
/Users/yuriramocan/.rvm/gems/ruby-2.2.2/gems/activesupport-4.2.3/lib/active_support/callbacks.rb:553:in `block (2 levels) in compile'
/Users/yuriramocan/.rvm/gems/ruby-2.2.2/gems/activesupport-4.2.3/lib/active_support/callbacks.rb:503:in `call'
/Users/yuriramocan/.rvm/gems/ruby-2.2.2/gems/activesupport-4.2.3/lib/active_support/callbacks.rb:503:in `call'
/Users/yuriramocan/.rvm/gems/ruby-2.2.2/gems/activesupport-4.2.3/lib/active_support/callbacks.rb:88:in `run_callbacks'
/Users/yuriramocan/.rvm/gems/ruby-2.2.2/gems/activerecord-4.2.3/lib/active_record/callbacks.rb:302:in `create_or_update'
/Users/yuriramocan/.rvm/gems/ruby-2.2.2/gems/activerecord-4.2.3/lib/active_record/persistence.rb:142:in `save!'
/Users/yuriramocan/.rvm/gems/ruby-2.2.2/gems/activerecord-4.2.3/lib/active_record/validations.rb:43:in `save!'
/Users/yuriramocan/.rvm/gems/ruby-2.2.2/gems/activerecord-4.2.3/lib/active_record/attribute_methods/dirty.rb:29:in `save!'
/Users/yuriramocan/.rvm/gems/ruby-2.2.2/gems/activerecord-4.2.3/lib/active_record/transactions.rb:291:in `block in save!'
/Users/yuriramocan/.rvm/gems/ruby-2.2.2/gems/activerecord-4.2.3/lib/active_record/transactions.rb:351:in `block in with_transaction_returning_status'
/Users/yuriramocan/.rvm/gems/ruby-2.2.2/gems/activerecord-4.2.3/lib/active_record/connection_adapters/abstract/database_statements.rb:213:in `block in transaction'
/Users/yuriramocan/.rvm/gems/ruby-2.2.2/gems/activerecord-4.2.3/lib/active_record/connection_adapters/abstract/transaction.rb:184:in `within_new_transaction'
/Users/yuriramocan/.rvm/gems/ruby-2.2.2/gems/activerecord-4.2.3/lib/active_record/connection_adapters/abstract/database_statements.rb:213:in `transaction'
/Users/yuriramocan/.rvm/gems/ruby-2.2.2/gems/activerecord-4.2.3/lib/active_record/transactions.rb:220:in `transaction'
/Users/yuriramocan/.rvm/gems/ruby-2.2.2/gems/activerecord-4.2.3/lib/active_record/transactions.rb:348:in `with_transaction_returning_status'
/Users/yuriramocan/.rvm/gems/ruby-2.2.2/gems/activerecord-4.2.3/lib/active_record/transactions.rb:291:in `save!'
/Users/yuriramocan/.rvm/gems/ruby-2.2.2/gems/activerecord-4.2.3/lib/active_record/persistence.rb:51:in `create!'
/Users/yuriramocan/Development/ruby_rails/db/seeds.rb:1:in `<top (required)>'
/Users/yuriramocan/.rvm/gems/ruby-2.2.2/gems/activesupport-4.2.3/lib/active_support/dependencies.rb:268:in `load'
/Users/yuriramocan/.rvm/gems/ruby-2.2.2/gems/activesupport-4.2.3/lib/active_support/dependencies.rb:268:in `block in load'
/Users/yuriramocan/.rvm/gems/ruby-2.2.2/gems/activesupport-4.2.3/lib/active_support/dependencies.rb:240:in `load_dependency'
/Users/yuriramocan/.rvm/gems/ruby-2.2.2/gems/activesupport-4.2.3/lib/active_support/dependencies.rb:268:in `load'
/Users/yuriramocan/.rvm/gems/ruby-2.2.2/gems/railties-4.2.3/lib/rails/engine.rb:547:in `load_seed'
/Users/yuriramocan/.rvm/gems/ruby-2.2.2/gems/activerecord-4.2.3/lib/active_record/tasks/database_tasks.rb:250:in `load_seed'
/Users/yuriramocan/.rvm/gems/ruby-2.2.2/gems/activerecord-4.2.3/lib/active_record/railties/databases.rake:180:in `block (2 levels) in <top (required)>'
/Users/yuriramocan/.rvm/rubies/ruby-2.2.2/lib/ruby/2.2.0/rake/task.rb:240:in `call'
/Users/yuriramocan/.rvm/rubies/ruby-2.2.2/lib/ruby/2.2.0/rake/task.rb:240:in `block in execute'
/Users/yuriramocan/.rvm/rubies/ruby-2.2.2/lib/ruby/2.2.0/rake/task.rb:235:in `each'
/Users/yuriramocan/.rvm/rubies/ruby-2.2.2/lib/ruby/2.2.0/rake/task.rb:235:in `execute'
/Users/yuriramocan/.rvm/rubies/ruby-2.2.2/lib/ruby/2.2.0/rake/task.rb:179:in `block in invoke_with_call_chain'
/Users/yuriramocan/.rvm/rubies/ruby-2.2.2/lib/ruby/2.2.0/monitor.rb:211:in `mon_synchronize'
/Users/yuriramocan/.rvm/rubies/ruby-2.2.2/lib/ruby/2.2.0/rake/task.rb:172:in `invoke_with_call_chain'
/Users/yuriramocan/.rvm/rubies/ruby-2.2.2/lib/ruby/2.2.0/rake/task.rb:165:in `invoke'
/Users/yuriramocan/.rvm/rubies/ruby-2.2.2/lib/ruby/2.2.0/rake/application.rb:150:in `invoke_task'
/Users/yuriramocan/.rvm/rubies/ruby-2.2.2/lib/ruby/2.2.0/rake/application.rb:106:in `block (2 levels) in top_level'
/Users/yuriramocan/.rvm/rubies/ruby-2.2.2/lib/ruby/2.2.0/rake/application.rb:106:in `each'
/Users/yuriramocan/.rvm/rubies/ruby-2.2.2/lib/ruby/2.2.0/rake/application.rb:106:in `block in top_level'
/Users/yuriramocan/.rvm/rubies/ruby-2.2.2/lib/ruby/2.2.0/rake/application.rb:115:in `run_with_threads'
/Users/yuriramocan/.rvm/rubies/ruby-2.2.2/lib/ruby/2.2.0/rake/application.rb:100:in `top_level'
/Users/yuriramocan/.rvm/rubies/ruby-2.2.2/lib/ruby/2.2.0/rake/application.rb:78:in `block in run'
/Users/yuriramocan/.rvm/rubies/ruby-2.2.2/lib/ruby/2.2.0/rake/application.rb:176:in `standard_exception_handling'
/Users/yuriramocan/.rvm/rubies/ruby-2.2.2/lib/ruby/2.2.0/rake/application.rb:75:in `run'
/Users/yuriramocan/.rvm/rubies/ruby-2.2.2/bin/rake:33:in `<main>'
Tasks: TOP => db:seed

Кроме того, вот мой файл seeds.rb для наглядности:

User.create!(name:  "Example User",
             email: "[email protected]",
             password:              "foobar",
             password_confirmation: "foobar",
             admin: true,
             activated: true,
             activated_at: Time.zone.now)

99.times do |n|
  name  = Faker::Name.name
  email = "example-#{n+1}@railstutorial.org"
  password = "password"
  User.create!(name:  name,
               email: email,
               password:              password,
               password_confirmation: password,
               activated: true,
               activated_at: Time.zone.now)
end

Может ли кто-нибудь помочь мне с этой ошибкой? Последние две недели меня это бесило. Спасибо.


person Yuri    schedule 19.08.2015    source источник


Ответы (2)


Вы не определили методы класса digest, это должно выглядеть примерно так

# Returns the hash digest of the given string.
  def User.digest(string)
    cost = ActiveModel::SecurePassword.min_cost ? BCrypt::Engine::MIN_COST :
                                                  BCrypt::Engine.cost
    BCrypt::Password.create(string, cost: cost)
  end

Код скопирован у Майкла Хартла https://www.railstutorial.org/book/log_in_log_out

person Rahul Singh    schedule 19.08.2015
comment
Вау, да! Вот оно. Я полностью пропустил это. Большое спасибо. @Рахул - person Yuri; 19.08.2015

Похоже, вы пропустили листинг 8.18:

def User.digest(string)
  cost = ActiveModel::SecurePassword.min_cost ? BCrypt::Engine::MIN_COST :
                                                BCrypt::Engine.cost
  BCrypt::Password.create(string, cost: cost)
end
person Anthony Atkinson    schedule 19.08.2015