Rails - before_save не работает? - PullRequest
8 голосов
/ 13 июня 2011

Я следую учебному пособию Майкла Хартла по RoR, и оно охватывает основы шифрования паролей. Это модель пользователя в ее нынешнем виде:

class User < ActiveRecord::Base
    attr_accessor :password

    attr_accessible :name, :email,: password, :password_confirmation

    email_regex = /^[A-Za-z0-9._+-]+@[A-Za-z0-9._-]+\.[A-Za-z0-9._-]+[A-Za-z]$/
                                              #tests for valid email addresses.

    validates :name, :presence => true,
                     :length => {:maximum => 50}
    validates :email, :presence => true,
                      :format => {:with => email_regex},
                      :uniqueness => {:case_sensitive => false}
    validates :password, :presence => true,
                         :length => {:maximum => 20, :minimum => 6},
                         :confirmation => true

    before_save :encrypt_password

    private

        def encrypt_password
            @encrypted_password = encrypt(password)
        end

        def encrypt(string)
            string
        end
end

(Очевидно, что шифрование не выполняется, потому что метод шифрования на самом деле не реализован, но это не мой вопрос) Затем я написал следующую спецификацию (согласно учебнику):

require 'spec_helper'

describe User do

    before(:each) do
        @attr = { :name => "Example User", :email => "user@example.com",
                  :password => "abc123", :password_confirmation => "abc123"}
    end

    describe "password encryption" do

        before(:each) do
            @user = User.create!(@attr) # we are going to need a valid user in order
                                        # for these tests to run.
        end

        it "should have an encrypted password attribute" do
            @user.should respond_to(:encrypted_password)
        end

        it "should set the encrypted password upon user creation" do
            @user.encrypted_password.should_not be_blank
        end

    end
end

Первый из этих тестов пройден, но поскольку @user.encrypted_password равен нулю, второй тест не пройден. Но я не понимаю, почему он равен nil, поскольку метод encrypt_password должен вызываться before_save. Я знаю, что, должно быть, что-то упустил - может кто-нибудь объяснить, пожалуйста?

Ответы [ 2 ]

20 голосов
/ 13 июня 2011

Неверный метод encrypt_password, он должен гласить:

def encrypt_password
  self.encrypted_password = encrypt(password)
end

Обратите внимание на использование self, которое будет правильно устанавливать атрибут для пользовательского объекта, а не создавать переменную экземпляра, которая будет забыта.

0 голосов
/ 30 августа 2013

Это старый вопрос, и это скорее комментарий, но у меня пока недостаточно репутации, чтобы комментировать. Просто хотел связать и этот вопрос, так как он подробно объясняет self.

Почему self не всегда необходим в ruby ​​/ rails / activerecord?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...