3

我有一個在多個模型中重複的方法。我是否應該在多個模型中重複使用該代碼,或者是否有方法將該方法包含在一個地方並使其可用於多個模型?如何重構發生在多個模型中的方法?

# Returns true if the given token matches the digest. 
    def authenticated?(attribute, token) 
    digest = send("#{attribute}_digest") 
    return false if digest.nil? 
    BCrypt::Password.new(digest).is_password?(token) 
    end 
+1

嘗試使用顧慮。 http://api.rubyonrails.org/classes/ActiveSupport/Concern.html – Kkulikovskis

回答

4

你最好使用concern,雖然在理論上,你也可以使用一個superclass


Concerns

這是標準的Rails的功能:

#app/models/concerns/auth.rb 
module Auth 
    extend ActiveSupport::Concern 

    def authenticated?(attribute, token) 
    digest = send("#{attribute}_digest") 
    return false if digest.nil? 
    BCrypt::Password.new(digest).is_password?(token) 
    end 
end 

然後你只需要包含auth在你的模型:

#app/models/your_model.rb 
class YourModel < ActiveRecord::Base 
    include Auth 
end 

Excellent writeup here


超類

另一種方法是創建一個 「超」。

這將是hacky(因爲它是用另一個模型填充ActiveRecord方法鏈),但可能會有趣的嘗試。

#app/models/auth.rb 
class Auth < ActiveRecord::Base 
    def authenticate? 
    .... 
    end 
end 

#app/models/user.rb 
class User < Auth 
    self.table_name = self.model_name.plural 
end 

誠實,這種方法似乎哈克,但它可以讓你延長超過concern會更加模型功能。

參考文獻: