Rails 4从头开始验证:before_create vs before_save

时间:2014-02-10 17:24:17

标签: ruby-on-rails authentication before-save

有人可以解释为什么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

2 个答案:

答案 0 :(得分:1)

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

如果使用“保存”方法,则必须先进行初始化然后保存。

所以,我想这对于before_create不起作用,只是因为这一刻你在初始化的实例中没有密码。

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

缅怀: create = new +同时保存,所以before_create你没有任何东西。 并且保存必须使用已初始化的内容。

我希望我已经清楚了!

答案 1 :(得分:0)

不幸的是,before_create:encrypt_password和before_save:encrypt_password都正确地将加密的字符串保存到数据库中,如下所示:after_validation。肯定会有一些我意外修复的错误,或者我没有错误并且暂时消失的错误。