engine/lib/locomotive/mongoid/patches.rb

139 lines
4.5 KiB
Ruby

require 'mongoid'
# require 'mongoid/document'
module Mongoid #:nodoc:
module Validations #:nodoc:
class AssociatedValidator < ActiveModel::EachValidator
def validate_each(document, attribute, value)
values = value.is_a?(Array) ? value : [ value ]
return if values.collect { |doc| doc.nil? || doc.valid? }.all?
document.errors.add(attribute, :invalid, options.merge(:value => value)) # was causing "can't modify frozen hash"
end
end
end
end
# Mongoid causes the following warning "Collection#group no longer take a list of paramters. This usage is deprecated.Check out the new API at http://api.mongodb.org/ruby/current/Mongo/Collection.html#group-instance_method"
# it's already corrected in the mongoid master branch so waiting for the new gem to remove this patch
module Mongoid #:nodoc:
module Contexts #:nodoc:
class Mongo
def aggregate
klass.collection.group(
:key => options[:fields],
:cond => selector,
:initial => { :count => 0 },
:reduce => Javascript.aggregate
)
end
def group
klass.collection.group(
:key => options[:fields],
:cond => selector,
:initial => { :group => [] },
:reduce => Javascript.group
).collect do |docs|
docs["group"] = docs["group"].collect do |attrs|
Mongoid::Factory.build(klass, attrs)
end
docs
end
end
def grouped(start, field, reduce)
collection = klass.collection.group(
:cond => selector,
:initial => { start => "start" },
:reduce => reduce.gsub("[field]", field)
)
collection.empty? ? nil : collection.first[start.to_s]
end
end
end
end
# # http://github.com/emk/mongoid/blob/503e346b1b7b250d682a12332ad9d5872f1575e6/lib/mongoid/atomicity.rb
# module Mongoid #:nodoc:
# module Atomicity #:nodoc:
# extend ActiveSupport::Concern
#
# def _updates
# processed = {}
#
# _children.inject({ "$set" => _sets, "$pushAll" => {}, :other => {} }) do |updates, child|
# changes = child._sets
# updates["$set"].update(changes)
# unless changes.empty?
# processed[child._conficting_modification_key] = true
# end
#
# # MongoDB does not allow "conflicting modifications" to be
# # performed in a single operation. Conflicting modifications are
# # detected by the 'haveConflictingMod' function in MongoDB.
# # Examination of the code suggests that two modifications (a $set
# # and a $pushAll, for example) conflict if (1) the key paths being
# # modified are equal or (2) one key path is a prefix of the other.
# # So a $set of 'addresses.0.street' will conflict with a $pushAll
# # to 'addresses', and we will need to split our update into two
# # pieces. We do not, however, attempt to match MongoDB's logic
# # exactly. Instead, we assume that two updates conflict if the
# # first component of the two key paths matches.
# if processed.has_key?(child._conficting_modification_key)
# target = :other
# else
# target = "$pushAll"
# end
#
# child._pushes.each do |attr, val|
# if updates[target].has_key?(attr)
# updates[target][attr] << val
# else
# updates[target].update({attr => [val]})
# end
# end
# updates
# end.delete_if do |key, value|
# value.empty?
# end
# end
#
# protected
# # Get the key used to check for conflicting modifications. For now, we
# # just use the first component of _path, and discard the first period
# # and everything that follows.
# def _conficting_modification_key
# _path.sub(/\..*/, '')
# end
# end
# end
# ## various patches
# module Mongoid #:nodoc:
# module Document
#
# def update_child_with_noname(child, clear = false)
# name = child.association_name
# return if name.blank? # fix a weird bug with mongoid-acts-as-tree
# update_child_without_noname(child, clear)
# end
#
# alias_method_chain :update_child, :noname
#
# # module ClassMethods
# #
# # def instantiate(attrs = nil, allocating = false) # used by carrierwave to back up the original file
# # document = super
# # document.send(:run_callbacks, :initialize) do
# # document
# # end
# # end
# #
# # end
#
# end
# end