2014-02-10 3 views
0

Может кто-нибудь объяснить, почему before_save: encrypt_password создает password_hash и password_salt в моей базе данных, но before_create: encrypt_password нет? Есть ли какая-то спецификация Rails 4 или Rails, которую я пропускаю? Ниже приведен фрагмент кода.Rails 4 Аутентификация с нуля: before_create vs before_save

include MembersHelper 

class Member < ActiveRecord::Base 
include ActiveModel::Validations 

has_many :parents, through: :reverse_relationships, source: :parent 
has_many :children, through: :relationships, source: :child 
has_many :relationships, foreign_key: "parent_id", dependent: :destroy 
has_many :reverse_relationships, foreign_key: "child_id", class_name: Relationship, dependent: :destroy 
has_many :spouses, through: :spouse_relationships, source: :spouse 
has_many :spouse_relationships, foreign_key: "member_id", dependent: :destroy 
has_many :images 

accepts_nested_attributes_for :parents, reject_if: proc { |attributes| attributes['first_name'].blank? && attributes['first_name'].blank? } 
accepts_nested_attributes_for :spouses, reject_if: proc { |attributes| attributes['first_name'].blank? && attributes['first_name'].blank? } 
accepts_nested_attributes_for :children, reject_if: proc { |attributes| attributes['first_name'].blank? && attributes['first_name'].blank? } 

attr_accessor :password 

##### 
before_save :encrypt_password ##### this does not work if i change it to before_create 
##### 
before_save :nil_or_downcase 
before_create :nil_or_downcase 
after_create :set_oldest_ancestor 
before_create { create_token(:remember_token) } 

before_destroy [ :set_ancestor_for_children, :destroy_spouse_id_of_spouse ] 

def encrypt_password 
    if password.present? 
     self.password_salt = BCrypt::Engine.generate_salt 
     self.password_hash = BCrypt::Engine.hash_secret(password, password_salt) 
    end 
end 
+0

зависит, когда вы создаете объект ... у него уже есть пароль? btw callbacks являются злыми – apneadiving

ответ

1

В методе «создать» вы одновременно инициализируете AND и сохраняете.

Когда у вас есть метод «save», вы должны сначала инициализировать, а затем сохранить его.

Итак, я думаю, что это не работает для before_create, только потому, что в этот момент у вас нет пароля в экземпляре, инициализированном.

И в «before_save» это работает, потому что если вы что-то сохраняете, вы уже инициализировали экземпляр с паролем, а затем его можно было зашифровать.

Вспоминая: create = new + сохранить в то же время, поэтому before_create у вас ничего нет. и сохранение должно идти с уже инициализированным.

Надеюсь, я был прост!

0

К сожалению, как before_create: encrypt_password, так и before_save: encrypt_password правильно сохраняют зашифрованную строку в базе данных, а именно: after_validation. Должно быть, была какая-то ошибка, которую я случайно установил, или тот, которого у меня нет, и просто исчез на данный момент.