如何像类一样实现Mongoid文档?

时间:2013-05-18 10:20:02

标签: ruby class inheritance

我正在构建一个小脚本,我需要在类中实现一个Mongoid文档,其中我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变量在该模块之外的任何位置都不可用。实现这个最简单的方法是什么?谢谢!

1 个答案:

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