Skip to content

Instantly share code, notes, and snippets.

@krasnoukhov
Created October 22, 2012 22:23
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 krasnoukhov/3935019 to your computer and use it in GitHub Desktop.
Save krasnoukhov/3935019 to your computer and use it in GitHub Desktop.
Prevents nil values to be saved in Mongoid document, removes them from existing documents when saving. Also fixes small issues with Mongoid aliases
module Mongoid
module Enhancements
extend ActiveSupport::Concern
module ClassHelpers
# Set callbacks
def enhance
self.set_callback(:save, :before, "remove_unnecessary_fields")
self.set_callback(:initialize, :after, "fill_boolean_fields")
end
# Get real attribute names
def real_attribute_names
self.fields.map { |_, x|
(x.options[:as] || x.name).to_s
}
end
end
module InstanceHelpers
# Fix json representation
def as_json(options = {})
options[:except] ||= {}
options[:except].concat(self.class.attribute_names - self.class.real_attribute_names).uniq!
options[:methods] ||= {}
options[:methods].concat(self.class.real_attribute_names - self.class.attribute_names).uniq!
super options
end
# Remove unnecessary fields
def remove_unnecessary_fields
self.class.fields.each { |key, field|
# Now field is nil (or it is bool and false)
if self.send(key).nil? || (field.options[:type] == Boolean && !field.options[:default] && self.send(key) == false)
# Simply remove from attributes
self.raw_attributes.delete(key)
# Unset field in existing document if it was not nil
if !self.new_record? && !self.send("#{key}_was").nil?
self.unset(key)
end
end
}
true
end
# Set booleans to false instead of nil
def fill_boolean_fields
self.class.fields.select { |_, field| field.options[:type] == Boolean }.each { |key, field|
self.send("#{key}=", false) if self.send(key).nil?
}
end
end
included do
extend Mongoid::Enhancements::ClassHelpers
include Mongoid::Enhancements::InstanceHelpers
enhance
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment