2014-01-08 32 views
3

我正在通過Michael Hartl的教程學習,但發現User類變得有點混亂。我想通過將大塊功能分成不同的mixin來清理它(使用new-ish ActiveSupport::Concern,而不是舊的self.included(klass)模式)。從實例方法中訪問ActiveSupport :: Concern類方法

我在Session的Session部分有點麻煩。

從 '模型/用戶/ session_management.rb':

require 'active_support/concern' 

module SessionManagement 
    extend ActiveSupport::Concern 

    included do 
    before_create :create_remember_token 
    end 

    private 
     def create_remember_token 
     self.remember_token = self.encrypt(self.new_remember_token) 
     end 

    module ClassMethods 
    def new_remember_token 
     SecureRandom.urlsafe_base64 
    end 

    def encrypt(token) 
     Digest::SHA1.hexdigest(token.to_s) 
    end 
    end 
end 

其中包括我在 '模型/ user.rb':

require 'user/authentication' 
require 'user/session_management' 

class User < ActiveRecord::Base 
    ... 

    include Authentication 
    include SessionManagement 

    ... 

end 

這驗證模塊正常工作(其中真的只是驗證和has_secure_password)。但是,create_remember_token實例方法正在試圖訪問encryptnew_remember_token類方法。

NoMethodError: 
    undefined method `new_remember_token' for #<User:0x007f8e17e338f0> 
    # ./app/models/user/session_management.rb:13:in 'create_remember_token' 
    # ./spec/models/user_spec.rb:152:in `block (4 levels) in <top (required)> 

我覺得我失去了一些明顯的東西。任何有識之士將不勝感激。提前致謝!

回答

6

這兩個方法是類方法,並且您正在實例上調用它們。試試:

def create_remember_token 
    self.remember_token = self.class.encrypt(self.class.new_remember_token) 
end 

或(最好)將它們移出ClassMethods模塊。

require 'active_support/concern' 

module SessionManagement 
    extend ActiveSupport::Concern 

    included do 
    before_create :create_remember_token 
    end 

    private 
    def create_remember_token 
     self.remember_token = encrypt(new_remember_token) 
    end 

    def new_remember_token 
     SecureRandom.urlsafe_base64 
    end 

    def encrypt(token) 
    Digest::SHA1.hexdigest(token.to_s) 
    end 

end 
+1

啊,這是有道理的。在本教程的上下文中,這些方法預計可以作爲User.new_remember_token和User.encrypt訪問,所以我猜這是第一個解決方案(儘管我理解這個論點)。謝謝! – TheWiseAxe