Created
November 6, 2011 22:32
-
-
Save asmuth/1343701 to your computer and use it in GitHub Desktop.
Dynamic (prefixed at runtime) collection names for mongoid models
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# uber-hacky dynamic collection names for MongoID models: | |
# | |
# class MyModel | |
# include Mongoid::PrefixableDocument # ...instead of Mongoid::Document | |
# include Mongoid::Timestamps | |
# | |
# field :foobar, :type => Integer | |
# | |
# def my_method; 123; end | |
# | |
# freeze_stack! # this needs to be the last line in your model! | |
# | |
# end | |
# | |
# m = MyModel.new | |
# => #<MyModelWrap _prefix: none, _id: 12312312, _type: nil > | |
# m.collection_name | |
# => "my_model" | |
# | |
# m = MyModel.prefix("foobar").new | |
# => #<FoobarMyModelWrap _prefix: foobar, _id: 12312312, _type: nil > | |
# m.collection_name | |
# => "foobar_my_model" | |
# | |
# ~paul (paul@paulasmuth.com) | |
module Mongoid | |
module PrefixableDocument | |
def self.included(base) | |
base.class_eval do | |
@@wrapped_stack = [] | |
@@wrapped_class = base | |
def self.prefix(_prefix=nil) | |
@@wrapped_class.clone.tap do |wrapper_klass| | |
wrapper_klass.class_eval do | |
@@wrapped_prefix = _prefix | |
include Mongoid::Document | |
def self.inspect | |
"#<#{@@wrapped_class.name} _prefix: #{@@wrapped_prefix||'none'}>" | |
end | |
def prefixed_inspect(inspection) | |
"#<#{@@wrapped_class.name} _prefix: #{@@wrapped_prefix||'none'}, _id: #{id}, #{inspection * ', '}>" | |
end | |
end | |
wrapper_klass.store_in([_prefix,@@wrapped_class.name.pluralize.downcase].compact.join("_")) | |
@@wrapped_stack.each{ |m,a| wrapper_klass.send(m,*a) } | |
end | |
end | |
def self.method_missing(_method, *args) | |
if @@wrapped_stack.frozen? | |
self.prefix.send(_method, *args) | |
else | |
@@wrapped_stack << [_method, args] | |
end | |
end | |
def self.freeze_stack! | |
@@wrapped_stack.freeze | |
end | |
end | |
end | |
end | |
module Inspection | |
def inspect | |
inspection = [] | |
inspection.concat(inspect_fields).concat(inspect_dynamic_fields) | |
return prefixed_inspect(inspection) if respond_to?(:prefixed_inspect) | |
"#<#{self.class.name} _id: #{id}, #{inspection * ', '}>" | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I inherited some code that used this gist. Word to the wise, don't use this with more than one class! Direct assignment of class variables in a mixins will have bad results. Replace the assignments:
with
Similarly, use :class_variable_get instead of direct reference of any @@ variable.
https://gist.github.com/jygeer/4492c261916d8d3a384f