如何在Rails模型中包含gem的类方法?

时间:2014-01-26 18:45:28

标签: ruby-on-rails ruby gem

我正在学习如何写一个宝石。我想添加一些我将在Rails中的用户模型中使用的方法。

# app/models/user.rb
class User
  include Mongoid::Document
  include Authme::Model  # here's my gem.

  field :password_digest, type: String
end
# Gemfile
gem 'authme'

现在,在我的宝石中,我有以下内容:

- authme
  - lib
    + authme
      - model.rb
    - authme.rb

以下是宝石的内容。

# lib/authme.rb
require 'authme/version'
require 'authme/model'
module Authme
end

# lib/authme/model.rb
module Authme
  module Model
    extend ActiveSupport::Concern

    included do
      include ActiveModel::SecurePassword
      has_secure_password validations: false
      before_create :create_session_token
    end

    module ClassMethods
      def new_session_token
        SecureRandom.urlsafe_base64
      end

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

    private

    def create_session_token
      self.session_token = self.class.encrypt(self.class.new_session_token)
    end
  end
end

我将此添加到我的gemspec:

spec.add_dependency "activesupport", "~> 4.0.1"

为了测试这一点,我在终端内试了User.new_session_token并得到了这个错误:

NoMethodError: undefined method `new_session_token' for User:Class

我做错了什么?我真的想测试这个,但我不在我的深度。我不确定如何测试用户类是否包含了gem模块。

1 个答案:

答案 0 :(得分:3)

问题在于您正在创建Authme::ModelAuthme::Model::ClassMethods,但实际上并未将new_session_token实际添加为Authme::Model的类方法。

如果您想将这些方法添加到Authme::Model,则需要执行类似

的操作
module Authme
  module Model
    module ClassMethods
      # define all of your class methods here...
    end

    extend ClassMethods
  end
end

这里的关键部分是Object#extend