如何为模型制作帮助器

时间:2013-03-12 15:34:11

标签: ruby-on-rails ruby-on-rails-3

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

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在其他型号中可用? 感谢

2 个答案:

答案 0 :(得分: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
  • independent:不要将user对象传递给类,只需让方法呈现一个随机标记并从模型中分配它。

答案 1 :(得分: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
    

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