Skip to content

Instantly share code, notes, and snippets.

@tilo
Created June 16, 2012 22:01
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tilo/2942627 to your computer and use it in GitHub Desktop.
Save tilo/2942627 to your computer and use it in GitHub Desktop.
Daily Collections with Mongoid 2.4
# Daily Collections With Mongoid 2.4
#
# Author: Tilo Sloboda, 2012-06-16
# Twitter: https://twitter.com/#!/tilosloboda
# GitHub: https://gist.github.com/tilo
# Gist: https://gist.github.com/2942627
#
# This can be useful if you need to re-import certain data every day
# and need to make sure that the latest daily collection is used in production
#
# USAGE:
# class Thing
# include DailyCollection
# include Mongoid::Document
# store_in todays_collection_name
# ...
# end
#
# My Use Case:
#
# One App instance is using the Thing collection for an API.
# At midnight a new instance of the App starts and loads a new nightly data dump for Things.
# Once the nightly data dump is loaded, we can tell the App which runs the API to switch
# to the new collection and we can delete any older collections in the nightly cron job.
#
# To switch collection names during runtime:
#
# Thing.update_collection_name()
#
# To drop old collections , including "things" collection:
#
# Thing.drop_old_collections # pass in "true" to really drop collections
#
module DailyCollection
def self.included(base)
# THIS ONLY WORKS FOR Mongoid 2.4
raise "INCORRECT Mongoid Version #{Mongoid::VERSION} instead of 2.4.x" if Mongoid::VERSION >= '2.5'
base.extend(ClassMethods)
end
module ClassMethods
def update_collection_name()
self.collection_name = self.todays_collection_name
self._collection = Mongoid::Collection.new(self, self.collection_name, {})
end
# name collections like this "things_20110712" instead of just 'things'
def todays_collection_name
self.to_s.pluralize.downcase + '_' + Date.today.strftime('%Y%m%d') # collection names should not contain '-'
end
def latest_collection_name
latest_collection.try(:name).to_s
end
def latest_collection
matching_collections.try(:sort).try(:last)
end
def matching_collections
collection_name = self.name.downcase.pluralize
collections = Mongoid.master.collections.select{|c| c.name =~ %r{^#{collection_name}}}
end
# Danger Will Robinson! Handle with care! pass in "true" to actually delete the old collections
def drop_old_collections(force = false)
collections = matching_collections
dropped_collections = []
collections.each do |c|
if c.name == collection_name || c.name < latest_collection_name # don't drop latest, even if it's old
puts "dropping Collection #{c.name}"
dropped_collections << c.name
c.try(:drop) if force # poof!
end
end
dropped_collections
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment