Skip to content

Instantly share code, notes, and snippets.

@jygeer
Forked from asmuth/mongoid_prefixable.rb
Last active June 30, 2019 12:01
Show Gist options
  • Save jygeer/4492c261916d8d3a384f to your computer and use it in GitHub Desktop.
Save jygeer/4492c261916d8d3a384f to your computer and use it in GitHub Desktop.
# 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)
#
# Modified for reuse in multiple classes
# - John (john@coolr.io, github:jygeer)
module Mongoid
module PrefixableDocument
def self.included(base)
base.send :class_variable_set, :@@wrapped_stack, []
base.send :class_variable_set, :@@wrapped_class, base
base.class_eval do
def self.prefix(_prefix=nil)
wrapped_class.clone.tap do |wrapper_klass|
wrapper_klass.class_eval do
self.send :class_variable_set, :@@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(collection: [_prefix,wrapped_class.name.pluralize.downcase].compact.join("_"))
wrapped_stack.each{ |m,a| wrapper_klass.send(m,*a) }
end
end
def self.wrapped_class
self.send :class_variable_get, :@@wrapped_class
end
def self.wrapped_stack
self.send :class_variable_get, :@@wrapped_stack
end
def self.wrapped_prefix
self.send :class_variable_get, :@@wrapped_prefix
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
@anhphamt
Copy link

Hi, just curious if this work with current mongoid version.

@milianoo
Copy link

Thanks, it works fine with mongoid version 7.0.2.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment