Reputation: 3456
Similar question, but user was not actually creating an ActiveRecord object.
Following Michael Hartl's tutorial, and I've hit a wall. There is a method call in before_save
that doesn't seem to be working. I have double checked that my code aligns with his and is syntactically valid (although I often overlook simple syntax errors).
class User < ActiveRecord::Base
before_create { :create_remember_token } <------ here
before_save { self.email = email.downcase }
validates :name, presence: true, length: { maximum: 30 }
VALID_EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-.?]+\.[a-z]{2,4}\z/i
validates :email, presence: true,
format: { with: VALID_EMAIL_REGEX },
uniqueness: { case_sensitive: false }
has_secure_password # automatically checks presence of password and confirmation
validates :password, length: { minimum: 6 }
def User.new_remember_token
SecureRandom.urlsafe_base64
end
def User.encrypt(token)
Digest::SHA1.hexdigest(token.to_s)
end
private
def create_remember_token
self.remember_token = User.encrypt(User.new_remember_token)
end
end
Here's a console session to show that the db schema includes a remember_token
, the class methods indeed work, yet something is wrong with the create callback.
2.0.0p247 :001 > User
=> User(id: integer, name: string, email: string, created_at: datetime, updated_at: datetime, password_digest: string, remember_token: string)
2.0.0p247 :002 > User.create(name:"Confused", email:"[email protected]", password:"password", password_confirmation:"password")
(0.1ms) begin transaction
User Exists (0.2ms) SELECT 1 AS one FROM "users" WHERE LOWER("users"."email") = LOWER('[email protected]') LIMIT 1
Binary data inserted for `string` type on column `password_digest`
SQL (3.9ms) INSERT INTO "users" ("created_at", "email", "name", "password_digest", "updated_at") VALUES (?, ?, ?, ?, ?) [["created_at", Wed, 09 Oct 2013 22:50:41 UTC +00:00], ["email", "[email protected]"], ["name", "Confused"], ["password_digest", "$2a$10$Pca7ZokAVlca/floQRY1KesM1SFoSfiUxWjEJ8xHyA4NJueK4GVbG"], ["updated_at", Wed, 09 Oct 2013 22:50:41 UTC +00:00]]
(101.5ms) commit transaction
=> #<User id: 9, name: "Confused", email: "[email protected]", created_at: "2013-10-09 22:50:41", updated_at: "2013-10-09 22:50:41", password_digest: "$2a$10$Pca7ZokAVlca/floQRY1KesM1SFoSfiUxWjEJ8xHyA4N...", remember_token: nil>
2.0.0p247 :003 >
2.0.0p247 :004 > token = User.new_remember_token
=> "md1vrpB2PH1VNMWaliuT6g"
2.0.0p247 :005 > User.encrypt(token)
=> "522d45ee2771c2cb36ffe6536b316ad004e5038b"
2.0.0p247 :006 >
2.0.0p247 :006 > User._create_callbacks.select { |cb| cb.kind.eql?(:before) }.collect(&:filter).include?(:create_remember_token)
=> false
Upvotes: 0
Views: 851
Reputation: 944
Just remove brackets, try:
before_create :create_remember_token
If you pass a block it is evaluated, if you pass symbol a method with given name is called.
Upvotes: 3