1

我正在构建一个小脚本,我需要在其中实现一个类似 Mongoid Document 的类,在其中我是include我的基本模块,然后我可以构建一个如下所示的类:

class MyClass
  include MyBaseModule
  field :some_field, :attr => 'attributes'
end

这是我最后一次尝试:

  module Model

    def initialize(keys = {})    
      puts @@keys
    end

    def method_missing sym, *args
      if sym =~ /^(\w+)=$/
        if @@keys.has_key?($1)
          @@keys[$1.to_sym] = args[0]
        else
          nil
        end
      else
        if @@keys.has_key?($1)
          @@keys[sym.to_sym]
        else
          nil
        end

      end
    end

    def inspect
      puts "#<#{self.class} @keys=#{@@keys.each {|k,v| "#{k} => #{v}"}}>"
    end

    def self.included(base)
      base.extend(ClassMethods)
    end

    def save
      @@keys.each do |k, v|
        SimpleMongo::connection.collection.insert({k => v})
      end
    end

    module ClassMethods
      def field(name, args)
        if @@keys.nil?
          @@keys = {}
        end
        @@keys[name.to_sym] = default_value
      end

    end

  end

Mongoid 文档如下所示:

class StoredFile
  include Mongoid::Document
  field :name, type: String
  field :description, type: String
  field :password, type: String
  field :public, type: Boolean
    field :shortlink, type: String
  mount_uploader :stored_file, StoredFileUploader
    before_save :gen_shortlink
    before_save :hash_password

    belongs_to :user

    def gen_shortlink
        self.shortlink = rand(36**10).to_s(36)
    end

    def public?
        self.public
    end

    def hash_password
        require 'bcrypt'
        self.password = BCrypt::Password.create(self.password).to_s
    end

    def check_pass(password)
        BCrypt::Password.new(self.password) == password
    end

  end

它不起作用,因为@@keys内部的变量在ClassMethods该模块之外的任何地方都不可用。实现这一点的最简单方法是什么?谢谢!

4

1 回答 1

1

实现它的最简单方法是拥有一个类变量 getter。

module Model
  def self.included(base)
    base.extend(ClassMethods)
  end

  module ClassMethods
    def keys
      @keys ||= {}
    end

    def field(name, opts)
      @keys ||= {}
      @keys[name] = opts
    end
  end

  def initialize(attributes)
    # stuff
    puts self.class.keys
  end
end
于 2013-05-18T10:43:25.610 回答