2013-03-20 4 views
10

Я делаю Rails tutorial by Michael Hartl, и я пришел к точке, где вы просто добавить:Как работает has_secure_password в моем классе модели?

has_secure_password 

для вашей модели класса и куча магии происходит.

Я понимаю, что этот метод исходит из модуля ActiveModel::SecurePassword, который входит в состав ActiveRecord::Base, который распространяется по моему классу.

Я не понимаю, что происходит, когда я добавляю эту строку в определение класса. Может кто-нибудь, пожалуйста, объясните, насколько это возможно. Я действительно хочу понять, что происходит, а не просто бросать вещи в мое приложение, не зная, как это работает.

(Если это помогает понять, почему я смущен, я родом из фона Java и я новичок в Ruby)

+0

Я думаю, что, наверное, этого достаточно, комментируя, ребята. –

ответ

8

Самый простой способ понять, что что-то делает, чтобы обратиться к источнику! В этом случае это будет ActiveModel::SecurePassword documentation. От того, вы можете увидеть, что has_secure_password делает это:

def has_secure_password 
    # Load bcrypt-ruby only when has_secure_password is used. 
    # This is to avoid ActiveModel (and by extension the entire framework) being dependent on a binary library. 
    gem 'bcrypt-ruby', '~> 3.0.0' 
    require 'bcrypt' 

    attr_reader :password 

    validates_confirmation_of :password 
    validates_presence_of  :password_digest 

    include InstanceMethodsOnActivation 

    if respond_to?(:attributes_protected_by_default) 
    def self.attributes_protected_by_default 
     super + ['password_digest'] 
    end 
    end 
end 

Для объяснения на английском языке, эту функцию:

  1. загружает bcrypt-ruby Gem и требует bcrypt. bcrypt - это безопасная функция хеширования, о которой вы можете узнать больше в Википедии.
  2. Добавляет атрибут только для чтения к модели с именем password.
  3. Подтверждает, что пароль подтвержден другим полем, называемым password_confirmation. Другими словами, вы должны ввести пароль дважды, чтобы подтвердить его.
  4. Обеспечивает, чтобы password_digest присутствовал до сохранения модели.
  5. Загрузите instance methods, который в этом случае равен authenticate (который возвращает true, если пароль верен, в противном случае - false) и password=, который шифрует переданный пароль в атрибут password_digest.
  6. Если у метода есть атрибуты, которые по умолчанию защищены, это также добавит password_digest к этому списку защищенных атрибутов. (Таким образом, предотвращение его назначения массой).

Дополнительную информацию можно найти на страницах ActiveModel::SecurePassword documentation и further documentation on its instance attributes.

+0

Я действительно смотрел на источник перед публикацией. Меня смущает вопрос: «require» и «include» сидят прямо в середине метода. Я пришел из Java, поэтому, когда я вижу 'require', мой ум говорит' import', который синтаксически корректен выше определения класса в Java. «Attr_reader», сидящий посредине метода, также немного запутан. Я прошел через Ruby Koans и не помню, чтобы натолкнулся на что-то подобное, но потом снова пробил через него довольно быстро. Мне кажется, что здесь отсутствует что-то принципиальное в Ruby. Можете ли вы указать мне в правильном направлении? –

+0

В отличие от Java, в Ruby вы можете «потребовать» в любом месте класса, чтобы использовать новые классы и методы из других источников. 'attr_reader' является аксессуаром: вы можете узнать больше о них [здесь] (http://www.rubyist.net/~slagell/ruby/accessors.html) (или просто Google для аксессуаров Ruby). – Veraticus

+0

Да, но аксессор объявлен в середине метода внутри модуля, который включает мой класс. Каждый пример, который я видел на аксессуарах (включая вашу ссылку), показывает их использование как часть определения класса. Я не уверен, как это относится к классу, к которому я вызываю этот метод. –

Смежные вопросы