2010-06-03 20:20:53 +00:00
require 'mongoid'
2010-10-10 14:37:34 +00:00
# require 'mongoid/document'
2010-06-03 20:20:53 +00:00
2010-09-01 14:26:00 +00:00
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
2011-01-26 13:07:33 +00:00
# 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
2010-08-31 21:53:30 +00:00
module Mongoid #:nodoc:
2011-01-26 13:07:33 +00:00
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 )
2010-08-31 21:53:30 +00:00
end
2011-01-26 13:07:33 +00:00
docs
2010-08-31 21:53:30 +00:00
end
end
2011-01-26 13:07:33 +00:00
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
2010-08-31 21:53:30 +00:00
end
end
2011-01-26 13:07:33 +00:00
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