Can someone explain why before_save :encrypt_password creates a password_hash and password_salt in my database, but before_create :encrypt_password does not? Is there some Rails 4 or Rails specification I'm missing? Code snippet below.
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
In a "create" method, you are initializing AND saving at the same time.
When you have a "save" method, you must first initialize and then save it.
So, i guess this does not work for before_create, just because still this moment you don´t have a password in a instance initialized.
And in "before_save", it works because if you are saving something, you already have initialized a instance with the password, and then it could be encrypted.
Remembering: create = new + save at the same time, so before_create you don´t have anything. and save must go with something already initialized.
I hope I have been clear!
Unfortunately, both before_create :encrypt_password and before_save :encrypt_password are properly saving the encrypted string into the database, as is :after_validation. There must have been some bug that I accidentally fixed, or one that I haven't and has simply disappeared for the moment.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.