0

有人可以解释为什么 before_save :encrypt_password 在我的数据库中创建了 password_hash 和 password_salt,但 before_create :encrypt_password 没有?我缺少一些 Rails 4 或 Rails 规范吗?下面的代码片段。

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
4

2 回答 2

1

在“创建”方法中,您正在同时初始化和保存。

当你有一个“保存”方法时,你必须先初始化然后保存它。

所以,我猜这对 before_create 不起作用,只是因为此时您在初始化的实例中还没有密码。

而在“before_save”中,它可以工作,因为如果你正在保存一些东西,你已经用密码初始化了一个实例,然后它可以被加密。

记住:create = new + save 同时进行,所以 before_create 你什么都没有。并且保存必须与已经初始化的东西一起使用。

我希望我已经清楚了!

于 2014-02-10T18:32:16.067 回答
0

不幸的是, before_create :encrypt_password 和 before_save :encrypt_password 都正确地将加密的字符串保存到数据库中,就像 :after_validation 一样。一定有一些我不小心修复的错误,或者我没有修复的错误,并且暂时消失了。

于 2014-02-10T19:05:30.940 回答