0

我的用户模型中有这个私有方法

class User < ActiveRecord::Base
  attr_accessible :email, :fullname, :password, :username
  has_secure_password
  before_create { generate_token(:remember_token) }
  .
  .
  private
    def generate_token(col)
      begin
        self[col] = SecureRandom.urlsafe_base64
      end while User.exists?(col => self[col])
    end

end

如何使 generate_token 在其他模型中可用?谢谢

4

2 回答 2

2

几种方法:

  • 稍微依赖:

做:

class User < ActiveRecord::Base

  before_create { User::Helpers.new(self).generate_token(:remember_token) }

  class Helpers < Struct.new(:user)
    def generate_token(col)
      begin
        user.send("#{col}=", SecureRandom.urlsafe_base64)
      end while User.exists?(col => user.send(col))
    end
  end
end
  • 独立:不要将user对象传递给类,只需让方法渲染一个随机标记并从模型中分配它。
于 2013-03-12T15:50:47.307 回答
2

这里有很多选择:

  • 使用简单的 ruby​​ 模块。

    module TokenRememberable
      private
      def generate_token(col)
        begin
          self[col] = SecureRandom.urlsafe_base64
        end while User.exists?(col => self[col])
      end 
    end
    
    class User < ActiveRecord::Base
      include TokenRememberable
      before_create { generate_token(:remember_token) }
    end
    
  • 对于更复杂的功能,使用 ActiveSupport::Concern :

    module TokenRememberable
      extend ActiveSupport::Concern
    
      # thanks to Concern, this block wil be evaluated 
      # in the context of the including class
      included do 
        before_create { generate_token(:remember_token) }
      end
    
      private
      def generate_token(col)
        begin
          self[col] = SecureRandom.urlsafe_base64
        end while self.class.exists?(col => self[col])
      end 
    end
    
    class User < ActiveRecord::Base
      include TokenRememberable
    end
    
  • 在专用类中提取功能,并可能使用组合

    # we only need a class method here, but you can also build 
    # full-fledged objects as you need
    class TokenGenerator 
      def self.generate_token
        # your generation logic here
      end  
    end
    
    class User
      def after_initialize
        @token_generator = TokenGenerator # or TokenGenerator.new( self ), for instance
      end
      attr_reader :token_generator
      delegate :generate_token, to: :token_generator # optionnaly use delegation
    end
    

注意:这不是真正的 Rails 问题,更多的是 Ruby 问题。你应该更多地记录你所使用的语言......模块是一个非常常见的习语。如果你需要,我可以给你一些很好的参考书

于 2013-03-12T15:51:10.470 回答