为什么没有在这里调用before_create?

时间:2013-10-09 23:14:03

标签: ruby-on-rails ruby

Similar question,但用户实际上并没有创建ActiveRecord对象。

按照迈克尔哈特的教程,我已经碰壁了。 before_save中的方法调用似乎不起作用。我已经仔细检查过我的代码与他的代码一致并且在语法上是有效的(尽管我经常忽略简单的语法错误)。

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

这是一个控制台会话,用于显示db模式包含remember_token,类方法确实有效,但 create 回调出现了问题。

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:"stack@overflow.com", password:"password", password_confirmation:"password")
   (0.1ms)  begin transaction
  User Exists (0.2ms)  SELECT 1 AS one FROM "users" WHERE LOWER("users"."email") = LOWER('stack@overflow.com') 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", "stack@overflow.com"], ["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: "stack@overflow.com", 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 

1 个答案:

答案 0 :(得分:3)

只需删除括号,请尝试:

before_create :create_remember_token 

如果传递一个块,则会对其进行评估,如果传递符号,则会调用具有给定名称的方法。