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