mongo_mapper 0.13.0 → 0.13.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/mongo_mapper.rb +3 -0
- data/lib/mongo_mapper/connection.rb +4 -3
- data/lib/mongo_mapper/document.rb +2 -0
- data/lib/mongo_mapper/extensions/symbol.rb +18 -0
- data/lib/mongo_mapper/plugins/accessible.rb +10 -1
- data/lib/mongo_mapper/plugins/associations/base.rb +5 -1
- data/lib/mongo_mapper/plugins/associations/belongs_to_association.rb +9 -0
- data/lib/mongo_mapper/plugins/associations/many_embedded_polymorphic_proxy.rb +0 -0
- data/lib/mongo_mapper/plugins/associations/many_embedded_proxy.rb +0 -0
- data/lib/mongo_mapper/plugins/associations/one_embedded_polymorphic_proxy.rb +0 -0
- data/lib/mongo_mapper/plugins/associations/one_embedded_proxy.rb +0 -0
- data/lib/mongo_mapper/plugins/associations/proxy.rb +2 -2
- data/lib/mongo_mapper/plugins/counter_cache.rb +78 -0
- data/lib/mongo_mapper/plugins/indexes.rb +0 -0
- data/lib/mongo_mapper/plugins/keys.rb +14 -2
- data/lib/mongo_mapper/plugins/modifiers.rb +0 -0
- data/lib/mongo_mapper/plugins/querying/decorated_plucky_query.rb +0 -0
- data/lib/mongo_mapper/plugins/rails.rb +1 -0
- data/lib/mongo_mapper/plugins/sci.rb +0 -0
- data/lib/mongo_mapper/plugins/stats.rb +19 -0
- data/lib/mongo_mapper/plugins/validations.rb +1 -1
- data/lib/mongo_mapper/railtie.rb +3 -3
- data/lib/mongo_mapper/version.rb +1 -1
- data/spec/functional/counter_cache_spec.rb +146 -0
- data/spec/functional/document_spec.rb +28 -0
- data/spec/functional/indexes_spec.rb +0 -0
- data/spec/functional/keys_spec.rb +31 -0
- data/spec/functional/sci_spec.rb +0 -0
- data/spec/functional/stats_spec.rb +74 -0
- data/spec/quality_spec.rb +51 -0
- data/spec/unit/associations/proxy_spec.rb +5 -0
- data/spec/unit/extensions_spec.rb +24 -0
- data/spec/unit/key_spec.rb +0 -0
- data/spec/unit/model_generator_spec.rb +0 -0
- data/spec/unit/rails_spec.rb +5 -0
- metadata +28 -22
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA1:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: 3e78985587a63e18283384630db3c316ee260b20
         | 
| 4 | 
            +
              data.tar.gz: 5f2d55cbe5df4c2f8322088cb9f0edfaa84a69e9
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: cf19d01f18a16676486f87db3e0db2c6894c6542f8492ed63b72cd9dbb24ae4dd90f26c5ec226a98fdc1636539a5a9a410c813bffba5923fa95a06fcc873bc4b
         | 
| 7 | 
            +
              data.tar.gz: 0b915ec964c1bafa1c3432061d91800029f291ce7799945830129d5c4109b1c2c21902ed8eb31ebb6c5648cb46c4775fe692d46614078ba001dabc95606ca3d0
         | 
    
        data/lib/mongo_mapper.rb
    CHANGED
    
    | @@ -1,5 +1,6 @@ | |
| 1 1 | 
             
            # encoding: UTF-8
         | 
| 2 2 | 
             
            require 'plucky'
         | 
| 3 | 
            +
            require 'active_support'
         | 
| 3 4 | 
             
            require 'active_support/core_ext'
         | 
| 4 5 | 
             
            require 'active_model'
         | 
| 5 6 | 
             
            require "mongo_mapper/railtie" if defined?(Rails)
         | 
| @@ -35,6 +36,7 @@ module MongoMapper | |
| 35 36 | 
             
                autoload :Callbacks,          'mongo_mapper/plugins/callbacks'
         | 
| 36 37 | 
             
                autoload :Caching,            'mongo_mapper/plugins/caching'
         | 
| 37 38 | 
             
                autoload :Clone,              'mongo_mapper/plugins/clone'
         | 
| 39 | 
            +
                autoload :CounterCache,       'mongo_mapper/plugins/counter_cache'
         | 
| 38 40 | 
             
                autoload :Dirty,              'mongo_mapper/plugins/dirty'
         | 
| 39 41 | 
             
                autoload :Document,           'mongo_mapper/plugins/document'
         | 
| 40 42 | 
             
                autoload :DynamicQuerying,    'mongo_mapper/plugins/dynamic_querying'
         | 
| @@ -57,6 +59,7 @@ module MongoMapper | |
| 57 59 | 
             
                autoload :Sci,                'mongo_mapper/plugins/sci'
         | 
| 58 60 | 
             
                autoload :Scopes,             'mongo_mapper/plugins/scopes'
         | 
| 59 61 | 
             
                autoload :Serialization,      'mongo_mapper/plugins/serialization'
         | 
| 62 | 
            +
                autoload :Stats,              'mongo_mapper/plugins/stats'
         | 
| 60 63 | 
             
                autoload :Timestamps,         'mongo_mapper/plugins/timestamps'
         | 
| 61 64 | 
             
                autoload :Userstamps,         'mongo_mapper/plugins/userstamps'
         | 
| 62 65 | 
             
                autoload :Validations,        'mongo_mapper/plugins/validations'
         | 
| @@ -78,11 +78,12 @@ module MongoMapper | |
| 78 78 | 
             
                    options[:ssl] = env['ssl']
         | 
| 79 79 | 
             
                  end
         | 
| 80 80 |  | 
| 81 | 
            -
                  MongoMapper.connection = if env | 
| 81 | 
            +
                  MongoMapper.connection = if env.key?('hosts')
         | 
| 82 | 
            +
                    klass = (env.key?("mongos") || env.key?("sharded")) ? Mongo::MongoShardedClient : Mongo::MongoReplicaSetClient
         | 
| 82 83 | 
             
                    if env['hosts'].first.is_a?(String)
         | 
| 83 | 
            -
                       | 
| 84 | 
            +
                      klass.new( env['hosts'], options )
         | 
| 84 85 | 
             
                    else
         | 
| 85 | 
            -
                       | 
| 86 | 
            +
                      klass.new( *env['hosts'].push(options) )
         | 
| 86 87 | 
             
                    end
         | 
| 87 88 | 
             
                  else
         | 
| 88 89 | 
             
                    Mongo::MongoClient.new(env['host'], env['port'], options)
         | 
| @@ -28,6 +28,7 @@ module MongoMapper | |
| 28 28 | 
             
                include Plugins::Sci
         | 
| 29 29 | 
             
                include Plugins::Scopes
         | 
| 30 30 | 
             
                include Plugins::Serialization
         | 
| 31 | 
            +
                include Plugins::Stats
         | 
| 31 32 | 
             
                include Plugins::Timestamps
         | 
| 32 33 | 
             
                include Plugins::Userstamps
         | 
| 33 34 | 
             
                include Plugins::Touch
         | 
| @@ -35,6 +36,7 @@ module MongoMapper | |
| 35 36 | 
             
                include Plugins::EmbeddedCallbacks
         | 
| 36 37 | 
             
                include Plugins::Callbacks # for now callbacks needs to be after validations
         | 
| 37 38 | 
             
                include Plugins::IdentityMap
         | 
| 39 | 
            +
                include Plugins::CounterCache
         | 
| 38 40 |  | 
| 39 41 | 
             
                included do
         | 
| 40 42 | 
             
                  extend Plugins
         | 
| @@ -0,0 +1,18 @@ | |
| 1 | 
            +
            # encoding: UTF-8
         | 
| 2 | 
            +
            module MongoMapper
         | 
| 3 | 
            +
              module Extensions
         | 
| 4 | 
            +
                module Symbol
         | 
| 5 | 
            +
                  def to_mongo(value)
         | 
| 6 | 
            +
                    value && value.to_s.to_sym
         | 
| 7 | 
            +
                  end
         | 
| 8 | 
            +
             | 
| 9 | 
            +
                  def from_mongo(value)
         | 
| 10 | 
            +
                    value && value.to_s.to_sym
         | 
| 11 | 
            +
                  end
         | 
| 12 | 
            +
                end
         | 
| 13 | 
            +
              end
         | 
| 14 | 
            +
            end
         | 
| 15 | 
            +
             | 
| 16 | 
            +
            class Symbol
         | 
| 17 | 
            +
              extend MongoMapper::Extensions::Symbol
         | 
| 18 | 
            +
            end
         | 
| @@ -45,7 +45,16 @@ module MongoMapper | |
| 45 45 | 
             
                  protected
         | 
| 46 46 | 
             
                    def filter_inaccessible_attrs(attrs)
         | 
| 47 47 | 
             
                      return attrs if !accessible_attributes? || attrs.blank?
         | 
| 48 | 
            -
                      attrs.dup.delete_if { |key, val|  | 
| 48 | 
            +
                      attrs.dup.delete_if { |key, val| attribute_inaccessible?(key.to_sym) }
         | 
| 49 | 
            +
                    end
         | 
| 50 | 
            +
             | 
| 51 | 
            +
                    def attribute_inaccessible?(attribute)
         | 
| 52 | 
            +
                      unless accessible_attributes.include?(attribute)
         | 
| 53 | 
            +
                        message = "Can't mass-assign protected attribute: #{attribute}"
         | 
| 54 | 
            +
                        MongoMapper.logger ? MongoMapper.logger.warn(message) : puts(message)
         | 
| 55 | 
            +
             | 
| 56 | 
            +
                        return true
         | 
| 57 | 
            +
                      end
         | 
| 49 58 | 
             
                    end
         | 
| 50 59 | 
             
                end
         | 
| 51 60 | 
             
              end
         | 
| @@ -6,7 +6,7 @@ module MongoMapper | |
| 6 6 | 
             
                    attr_reader :name, :options, :query_options
         | 
| 7 7 |  | 
| 8 8 | 
             
                    # Options that should not be considered MongoDB query options/criteria
         | 
| 9 | 
            -
                    AssociationOptions = [:as, :class, :class_name, :dependent, :extend, :foreign_key, :in, :polymorphic, :autosave, :touch]
         | 
| 9 | 
            +
                    AssociationOptions = [:as, :class, :class_name, :dependent, :extend, :foreign_key, :in, :polymorphic, :autosave, :touch, :counter_cache]
         | 
| 10 10 |  | 
| 11 11 | 
             
                    def initialize(name, options={}, &extension)
         | 
| 12 12 | 
             
                      @name, @options, @query_options, @original_options = name.to_sym, {}, {}, options
         | 
| @@ -43,6 +43,10 @@ module MongoMapper | |
| 43 43 | 
             
                      !!@options[:touch]
         | 
| 44 44 | 
             
                    end
         | 
| 45 45 |  | 
| 46 | 
            +
                    def counter_cache?
         | 
| 47 | 
            +
                      !!@options[:counter_cache]
         | 
| 48 | 
            +
                    end
         | 
| 49 | 
            +
             | 
| 46 50 | 
             
                    def type_key_name
         | 
| 47 51 | 
             
                      "_type"
         | 
| 48 52 | 
             
                    end
         | 
| @@ -20,6 +20,7 @@ module MongoMapper | |
| 20 20 | 
             
                      model.key type_key_name, String unless model.key?(type_key_name) if polymorphic?
         | 
| 21 21 | 
             
                      super
         | 
| 22 22 | 
             
                      add_touch_callbacks if touch?
         | 
| 23 | 
            +
                      add_counter_cache if counter_cache?
         | 
| 23 24 | 
             
                    end
         | 
| 24 25 |  | 
| 25 26 | 
             
                    def autosave?
         | 
| @@ -46,7 +47,15 @@ module MongoMapper | |
| 46 47 | 
             
                      @model.after_save(method_name)
         | 
| 47 48 | 
             
                      @model.after_touch(method_name)
         | 
| 48 49 | 
             
                      @model.after_destroy(method_name)
         | 
| 50 | 
            +
                    end
         | 
| 51 | 
            +
             | 
| 52 | 
            +
                    def add_counter_cache
         | 
| 53 | 
            +
                      options = {}
         | 
| 54 | 
            +
                      if @options[:counter_cache] && @options[:counter_cache] != true
         | 
| 55 | 
            +
                        options[:field] = @options[:counter_cache]
         | 
| 56 | 
            +
                      end
         | 
| 49 57 |  | 
| 58 | 
            +
                      @model.counter_cache name, options
         | 
| 50 59 | 
             
                    end
         | 
| 51 60 | 
             
                  end
         | 
| 52 61 | 
             
                end
         | 
| 
            File without changes
         | 
| 
            File without changes
         | 
| 
            File without changes
         | 
| 
            File without changes
         | 
| @@ -91,12 +91,12 @@ module MongoMapper | |
| 91 91 | 
             
                      proxy_respond_to?(*args) || (load_target && target.respond_to?(*args))
         | 
| 92 92 | 
             
                    end
         | 
| 93 93 |  | 
| 94 | 
            -
                    def send(method, *args)
         | 
| 94 | 
            +
                    def send(method, *args, &block)
         | 
| 95 95 | 
             
                      if proxy_respond_to?(method, true)
         | 
| 96 96 | 
             
                        super
         | 
| 97 97 | 
             
                      else
         | 
| 98 98 | 
             
                        load_target
         | 
| 99 | 
            -
                        target.send(method, *args)
         | 
| 99 | 
            +
                        target.send(method, *args, &block)
         | 
| 100 100 | 
             
                      end
         | 
| 101 101 | 
             
                    end
         | 
| 102 102 |  | 
| @@ -0,0 +1,78 @@ | |
| 1 | 
            +
            module MongoMapper
         | 
| 2 | 
            +
              module Plugins
         | 
| 3 | 
            +
                # Counter Caching for MongoMapper::Document
         | 
| 4 | 
            +
                #
         | 
| 5 | 
            +
                # Examples:
         | 
| 6 | 
            +
                #
         | 
| 7 | 
            +
                #   class Post
         | 
| 8 | 
            +
                #     belongs_to :user
         | 
| 9 | 
            +
                #     counter_cache :user
         | 
| 10 | 
            +
                #   end
         | 
| 11 | 
            +
                #
         | 
| 12 | 
            +
                #   or:
         | 
| 13 | 
            +
                #
         | 
| 14 | 
            +
                #   class Post
         | 
| 15 | 
            +
                #     belongs_to :user
         | 
| 16 | 
            +
                #     counter_cache :user, :custom_posts_count
         | 
| 17 | 
            +
                #   end
         | 
| 18 | 
            +
                #
         | 
| 19 | 
            +
                # Field names follow rails conventions, so counter_cache :user will increment the Integer field `posts_count' on User
         | 
| 20 | 
            +
                #
         | 
| 21 | 
            +
                # Alternatively, you can also use the more common ActiveRecord syntax:
         | 
| 22 | 
            +
                #
         | 
| 23 | 
            +
                #   class Post
         | 
| 24 | 
            +
                #     belongs_to :user, :counter_cache => true
         | 
| 25 | 
            +
                #   end
         | 
| 26 | 
            +
                #
         | 
| 27 | 
            +
                # Or with an alternative field name:
         | 
| 28 | 
            +
                #
         | 
| 29 | 
            +
                #   class Post
         | 
| 30 | 
            +
                #     belongs_to :user, :counter_cache => :custom_posts_count
         | 
| 31 | 
            +
                #   end
         | 
| 32 | 
            +
                #
         | 
| 33 | 
            +
                module CounterCache
         | 
| 34 | 
            +
                  class InvalidCounterCacheError < StandardError; end
         | 
| 35 | 
            +
             | 
| 36 | 
            +
                  extend ActiveSupport::Concern
         | 
| 37 | 
            +
             | 
| 38 | 
            +
                  module ClassMethods
         | 
| 39 | 
            +
                    def counter_cache(association_name, options = {})
         | 
| 40 | 
            +
                      options.symbolize_keys!
         | 
| 41 | 
            +
             | 
| 42 | 
            +
                      field = options[:field] ?
         | 
| 43 | 
            +
                        options[:field] :
         | 
| 44 | 
            +
                        "#{self.collection_name.gsub(/.*\./, '')}_count"
         | 
| 45 | 
            +
             | 
| 46 | 
            +
                      association = associations[association_name]
         | 
| 47 | 
            +
             | 
| 48 | 
            +
                      if !association
         | 
| 49 | 
            +
                        raise InvalidCounterCacheError, "You must define an association with name `#{association_name}' on model #{self}"
         | 
| 50 | 
            +
                      end
         | 
| 51 | 
            +
             | 
| 52 | 
            +
                      association_class = association.klass
         | 
| 53 | 
            +
                      key_names = association_class.keys.keys
         | 
| 54 | 
            +
             | 
| 55 | 
            +
                      if !key_names.include?(field.to_s)
         | 
| 56 | 
            +
                        raise InvalidCounterCacheError, "Missing `key #{field.to_sym.inspect}, Integer, :default => 0' on model #{association_class}"
         | 
| 57 | 
            +
                      end
         | 
| 58 | 
            +
             | 
| 59 | 
            +
                      after_create do
         | 
| 60 | 
            +
                        if obj = self.send(association_name)
         | 
| 61 | 
            +
                          obj.increment(field => 1)
         | 
| 62 | 
            +
                          obj.write_attribute(field, obj.read_attribute(field) + 1)
         | 
| 63 | 
            +
                        end
         | 
| 64 | 
            +
                        true
         | 
| 65 | 
            +
                      end
         | 
| 66 | 
            +
             | 
| 67 | 
            +
                      after_destroy do
         | 
| 68 | 
            +
                        if obj = self.send(association_name)
         | 
| 69 | 
            +
                          obj.decrement(field => 1)
         | 
| 70 | 
            +
                          obj.write_attribute(field, obj.read_attribute(field) - 1)
         | 
| 71 | 
            +
                        end
         | 
| 72 | 
            +
                        true
         | 
| 73 | 
            +
                      end
         | 
| 74 | 
            +
                    end
         | 
| 75 | 
            +
                  end
         | 
| 76 | 
            +
                end
         | 
| 77 | 
            +
              end
         | 
| 78 | 
            +
            end
         | 
| 
            File without changes
         | 
| @@ -246,8 +246,20 @@ module MongoMapper | |
| 246 246 | 
             
                        a_name = [name]
         | 
| 247 247 |  | 
| 248 248 | 
             
                        _validators.reject!{ |key, _| key == name }
         | 
| 249 | 
            -
                         | 
| 249 | 
            +
                        remove_validate_callbacks a_name
         | 
| 250 250 | 
             
                      end
         | 
| 251 | 
            +
             | 
| 252 | 
            +
                      def remove_validate_callbacks(a_name)
         | 
| 253 | 
            +
                        chain = _validate_callbacks.dup.reject do |callback|
         | 
| 254 | 
            +
                          f = callback.raw_filter
         | 
| 255 | 
            +
                          f.respond_to?(:attributes) && f.attributes == a_name
         | 
| 256 | 
            +
                        end
         | 
| 257 | 
            +
                        reset_callbacks(:validate)
         | 
| 258 | 
            +
                        chain.each do |callback|
         | 
| 259 | 
            +
                          set_callback 'validate', callback.raw_filter
         | 
| 260 | 
            +
                        end
         | 
| 261 | 
            +
                      end
         | 
| 262 | 
            +
             | 
| 251 263 | 
             
                  end
         | 
| 252 264 |  | 
| 253 265 | 
             
                  def initialize(attrs={})
         | 
| @@ -293,7 +305,7 @@ module MongoMapper | |
| 293 305 |  | 
| 294 306 | 
             
                      embedded_associations.each do |association|
         | 
| 295 307 | 
             
                        if documents = instance_variable_get(association.ivar)
         | 
| 296 | 
            -
                          if association. | 
| 308 | 
            +
                          if association.is_a?(Associations::OneAssociation)
         | 
| 297 309 | 
             
                            attrs[association.name] = documents.to_mongo
         | 
| 298 310 | 
             
                          else
         | 
| 299 311 | 
             
                            attrs[association.name] = documents.map(&:to_mongo)
         | 
| 
            File without changes
         | 
| 
            File without changes
         | 
| 
            File without changes
         | 
| @@ -0,0 +1,19 @@ | |
| 1 | 
            +
            # encoding: UTF-8
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module MongoMapper
         | 
| 4 | 
            +
              module Plugins
         | 
| 5 | 
            +
                module Stats
         | 
| 6 | 
            +
                  extend ActiveSupport::Concern
         | 
| 7 | 
            +
             | 
| 8 | 
            +
                  module ClassMethods
         | 
| 9 | 
            +
                    def stats
         | 
| 10 | 
            +
                      stats = collection.stats
         | 
| 11 | 
            +
             | 
| 12 | 
            +
                      Struct.new(*stats.keys.collect { |key| key.underscore.to_sym }).new(*stats.values)
         | 
| 13 | 
            +
                    rescue
         | 
| 14 | 
            +
                      nil
         | 
| 15 | 
            +
                    end
         | 
| 16 | 
            +
                  end
         | 
| 17 | 
            +
                end
         | 
| 18 | 
            +
              end
         | 
| 19 | 
            +
            end
         | 
| @@ -34,7 +34,7 @@ module MongoMapper | |
| 34 34 | 
             
                    end
         | 
| 35 35 |  | 
| 36 36 | 
             
                    if ::ActiveModel::VERSION::MAJOR < 4 ||
         | 
| 37 | 
            -
                      (::ActiveModel::VERSION::MAJOR == 4 && ::ActiveModel::VERSION::MINOR == 0) | 
| 37 | 
            +
                      (::ActiveModel::VERSION::MAJOR == 4 && ::ActiveModel::VERSION::MINOR == 0)
         | 
| 38 38 |  | 
| 39 39 | 
             
                      def setup(klass)
         | 
| 40 40 | 
             
                        @klass = klass
         | 
    
        data/lib/mongo_mapper/railtie.rb
    CHANGED
    
    | @@ -14,9 +14,9 @@ module MongoMapper | |
| 14 14 | 
             
                # Rescue responses similar to ActiveRecord.
         | 
| 15 15 | 
             
                # For rails 3.0 and 3.1
         | 
| 16 16 | 
             
                if Rails.version < "3.2"
         | 
| 17 | 
            -
                  ActionDispatch::ShowExceptions.rescue_responses['MongoMapper::DocumentNotFound']  = :not_found | 
| 18 | 
            -
                  ActionDispatch::ShowExceptions.rescue_responses['MongoMapper::InvalidKey']        = :unprocessable_entity | 
| 19 | 
            -
                  ActionDispatch::ShowExceptions.rescue_responses['MongoMapper::InvalidScheme']     = :unprocessable_entity | 
| 17 | 
            +
                  ActionDispatch::ShowExceptions.rescue_responses['MongoMapper::DocumentNotFound']  = :not_found
         | 
| 18 | 
            +
                  ActionDispatch::ShowExceptions.rescue_responses['MongoMapper::InvalidKey']        = :unprocessable_entity
         | 
| 19 | 
            +
                  ActionDispatch::ShowExceptions.rescue_responses['MongoMapper::InvalidScheme']     = :unprocessable_entity
         | 
| 20 20 | 
             
                  ActionDispatch::ShowExceptions.rescue_responses['MongoMapper::NotSupported']      = :unprocessable_entity
         | 
| 21 21 | 
             
                else
         | 
| 22 22 | 
             
                  # For rails 3.2 and 4.0
         | 
    
        data/lib/mongo_mapper/version.rb
    CHANGED
    
    
| @@ -0,0 +1,146 @@ | |
| 1 | 
            +
            require 'spec_helper'
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module CounterCacheFixtureModels
         | 
| 4 | 
            +
              class User
         | 
| 5 | 
            +
                include MongoMapper::Document
         | 
| 6 | 
            +
             | 
| 7 | 
            +
                key :posts_count, Integer, :default => 0
         | 
| 8 | 
            +
             | 
| 9 | 
            +
                has_many :posts,
         | 
| 10 | 
            +
                         :class_name => "CounterCacheFixtureModels::Post"
         | 
| 11 | 
            +
              end
         | 
| 12 | 
            +
             | 
| 13 | 
            +
              class Post
         | 
| 14 | 
            +
                include MongoMapper::Document
         | 
| 15 | 
            +
             | 
| 16 | 
            +
                key :comments_count, Integer, :default => 0
         | 
| 17 | 
            +
                key :some_custom_comments_count, Integer, :default => 0
         | 
| 18 | 
            +
             | 
| 19 | 
            +
                has_many :comments,
         | 
| 20 | 
            +
                         :class_name => "CounterCacheFixtureModels::Comment"
         | 
| 21 | 
            +
             | 
| 22 | 
            +
                belongs_to :user,
         | 
| 23 | 
            +
                           :counter_cache => true,
         | 
| 24 | 
            +
                           :class_name => "CounterCacheFixtureModels::User"
         | 
| 25 | 
            +
              end
         | 
| 26 | 
            +
             | 
| 27 | 
            +
              class Comment
         | 
| 28 | 
            +
                include MongoMapper::Document
         | 
| 29 | 
            +
             | 
| 30 | 
            +
                belongs_to :post,
         | 
| 31 | 
            +
                           :counter_cache => true,
         | 
| 32 | 
            +
                           :class_name => "CounterCacheFixtureModels::Post"
         | 
| 33 | 
            +
              end
         | 
| 34 | 
            +
             | 
| 35 | 
            +
              class CustomComment
         | 
| 36 | 
            +
                include MongoMapper::Document
         | 
| 37 | 
            +
             | 
| 38 | 
            +
                belongs_to :post,
         | 
| 39 | 
            +
                           :counter_cache => :some_custom_comments_count,
         | 
| 40 | 
            +
                           :class_name => "CounterCacheFixtureModels::Post"
         | 
| 41 | 
            +
              end
         | 
| 42 | 
            +
            end
         | 
| 43 | 
            +
             | 
| 44 | 
            +
            describe MongoMapper::Plugins::CounterCache do
         | 
| 45 | 
            +
              before do
         | 
| 46 | 
            +
                @post_class = CounterCacheFixtureModels::Post
         | 
| 47 | 
            +
                @comment_class = CounterCacheFixtureModels::Comment
         | 
| 48 | 
            +
                @user_class = CounterCacheFixtureModels::User
         | 
| 49 | 
            +
                @custom_comment_class = CounterCacheFixtureModels::CustomComment
         | 
| 50 | 
            +
              end
         | 
| 51 | 
            +
             | 
| 52 | 
            +
              it "should have a key with posts_count defaulting to 0" do
         | 
| 53 | 
            +
                @post_class.new.comments_count.should == 0
         | 
| 54 | 
            +
              end
         | 
| 55 | 
            +
             | 
| 56 | 
            +
              it "should update the count when a new object is created" do
         | 
| 57 | 
            +
                post = @post_class.new
         | 
| 58 | 
            +
                comment = @comment_class.new
         | 
| 59 | 
            +
             | 
| 60 | 
            +
                post.save!
         | 
| 61 | 
            +
             | 
| 62 | 
            +
                comment.post = post
         | 
| 63 | 
            +
                comment.save!
         | 
| 64 | 
            +
             | 
| 65 | 
            +
                post.reload
         | 
| 66 | 
            +
                post.comments_count.should == 1
         | 
| 67 | 
            +
             | 
| 68 | 
            +
                second_comment = @comment_class.new
         | 
| 69 | 
            +
                second_comment.post = post
         | 
| 70 | 
            +
                second_comment.save!
         | 
| 71 | 
            +
             | 
| 72 | 
            +
                post.reload
         | 
| 73 | 
            +
                post.comments_count.should == 2
         | 
| 74 | 
            +
              end
         | 
| 75 | 
            +
             | 
| 76 | 
            +
              it "should decrease the count by one when an object is destroyed" do
         | 
| 77 | 
            +
                post = @post_class.new
         | 
| 78 | 
            +
                comment = @comment_class.new
         | 
| 79 | 
            +
             | 
| 80 | 
            +
                post.save!
         | 
| 81 | 
            +
             | 
| 82 | 
            +
                comment.post = post
         | 
| 83 | 
            +
                comment.save!
         | 
| 84 | 
            +
             | 
| 85 | 
            +
                post.reload
         | 
| 86 | 
            +
                post.comments_count.should == 1
         | 
| 87 | 
            +
             | 
| 88 | 
            +
                comment.destroy
         | 
| 89 | 
            +
                post.reload
         | 
| 90 | 
            +
                post.comments_count.should == 0
         | 
| 91 | 
            +
              end
         | 
| 92 | 
            +
             | 
| 93 | 
            +
              it "should use the correct association name" do
         | 
| 94 | 
            +
                @user = @user_class.new
         | 
| 95 | 
            +
                @post = @post_class.new
         | 
| 96 | 
            +
             | 
| 97 | 
            +
                @user.save!
         | 
| 98 | 
            +
                @post.user = @user
         | 
| 99 | 
            +
                @post.save!
         | 
| 100 | 
            +
             | 
| 101 | 
            +
                @user.reload
         | 
| 102 | 
            +
                @user.posts_count.should == 1
         | 
| 103 | 
            +
              end
         | 
| 104 | 
            +
             | 
| 105 | 
            +
              it "should be able to use a custom field name" do
         | 
| 106 | 
            +
                @post = @post_class.new
         | 
| 107 | 
            +
                @custom_comment = @custom_comment_class.new
         | 
| 108 | 
            +
             | 
| 109 | 
            +
                @post.save!
         | 
| 110 | 
            +
                @custom_comment.post = @post
         | 
| 111 | 
            +
                @custom_comment.save!
         | 
| 112 | 
            +
             | 
| 113 | 
            +
                @post.reload
         | 
| 114 | 
            +
                @post.some_custom_comments_count.should == 1
         | 
| 115 | 
            +
              end
         | 
| 116 | 
            +
             | 
| 117 | 
            +
              it "should thrown an error if there is no association" do
         | 
| 118 | 
            +
                lambda {
         | 
| 119 | 
            +
                  CounterCacheFixtureModels.module_eval do
         | 
| 120 | 
            +
                    class CommentWithInvalidAssociation
         | 
| 121 | 
            +
                      include MongoMapper::Document
         | 
| 122 | 
            +
             | 
| 123 | 
            +
                      belongs_to :post,
         | 
| 124 | 
            +
                                 :class_name => "CounterCacheFixtureModels::Post"
         | 
| 125 | 
            +
             | 
| 126 | 
            +
                      counter_cache :foo
         | 
| 127 | 
            +
                    end
         | 
| 128 | 
            +
                  end
         | 
| 129 | 
            +
                }.should raise_error(MongoMapper::Plugins::CounterCache::InvalidCounterCacheError, "You must define an association with name `foo' on model CommentWithInvalidAssociation")
         | 
| 130 | 
            +
              end
         | 
| 131 | 
            +
             | 
| 132 | 
            +
              it "should thown a sensible error if the field is not defined on the target object" do
         | 
| 133 | 
            +
                lambda {
         | 
| 134 | 
            +
                  CounterCacheFixtureModels.module_eval do
         | 
| 135 | 
            +
                    class CommentWithBadRefenceField
         | 
| 136 | 
            +
                      include MongoMapper::Document
         | 
| 137 | 
            +
             | 
| 138 | 
            +
                      belongs_to :post,
         | 
| 139 | 
            +
                                 :class_name => "CounterCacheFixtureModels::Post"
         | 
| 140 | 
            +
             | 
| 141 | 
            +
                      counter_cache :post, :field => :invalid_field
         | 
| 142 | 
            +
                    end
         | 
| 143 | 
            +
                  end
         | 
| 144 | 
            +
                }.should raise_error(MongoMapper::Plugins::CounterCache::InvalidCounterCacheError, "Missing `key :invalid_field, Integer, :default => 0' on model CounterCacheFixtureModels::Post")
         | 
| 145 | 
            +
              end
         | 
| 146 | 
            +
            end
         | 
| @@ -130,6 +130,34 @@ describe "Document" do | |
| 130 130 | 
             
                end
         | 
| 131 131 | 
             
              end
         | 
| 132 132 |  | 
| 133 | 
            +
              context "symbol key" do
         | 
| 134 | 
            +
                before do
         | 
| 135 | 
            +
                  @document.key :foo, Symbol, :default => lambda { 123 }
         | 
| 136 | 
            +
                end
         | 
| 137 | 
            +
             | 
| 138 | 
            +
                it "should return default value" do
         | 
| 139 | 
            +
                  doc = @document.new
         | 
| 140 | 
            +
                  doc.foo.should == :'123'
         | 
| 141 | 
            +
                end
         | 
| 142 | 
            +
             | 
| 143 | 
            +
                it "should return symbol value" do
         | 
| 144 | 
            +
                  doc = @document.create :foo => 'qwerty'
         | 
| 145 | 
            +
                  doc.foo.should == :qwerty
         | 
| 146 | 
            +
             | 
| 147 | 
            +
                  doc.set :foo => 'poiuyt'
         | 
| 148 | 
            +
                  doc.reload
         | 
| 149 | 
            +
                  doc.foo.should == :poiuyt
         | 
| 150 | 
            +
             | 
| 151 | 
            +
                  doc.foo = 'asdf'
         | 
| 152 | 
            +
                  doc.foo.should == :asdf
         | 
| 153 | 
            +
                end
         | 
| 154 | 
            +
             | 
| 155 | 
            +
                it "should return typecasted value" do
         | 
| 156 | 
            +
                  doc = @document.new
         | 
| 157 | 
            +
                  (doc.foo = 'qwerty').should == 'qwerty'
         | 
| 158 | 
            +
                end
         | 
| 159 | 
            +
              end
         | 
| 160 | 
            +
             | 
| 133 161 | 
             
              it "should have instance method for collection" do
         | 
| 134 162 | 
             
                @document.new.collection.name.should == @document.collection.name
         | 
| 135 163 | 
             
              end
         | 
| 
            File without changes
         | 
| @@ -296,4 +296,35 @@ describe "Keys" do | |
| 296 296 | 
             
                  end
         | 
| 297 297 | 
             
                end
         | 
| 298 298 | 
             
              end
         | 
| 299 | 
            +
             | 
| 300 | 
            +
              describe "removing keys" do
         | 
| 301 | 
            +
                DocWithRemovedKey = Doc do
         | 
| 302 | 
            +
                  key :something
         | 
| 303 | 
            +
                  validates_uniqueness_of :something
         | 
| 304 | 
            +
                  remove_key :something
         | 
| 305 | 
            +
                end
         | 
| 306 | 
            +
             | 
| 307 | 
            +
                it 'should remove the key' do
         | 
| 308 | 
            +
                  DocWithRemovedKey.keys.should_not have_key "_something"
         | 
| 309 | 
            +
                end
         | 
| 310 | 
            +
             | 
| 311 | 
            +
                it 'should remove validations' do
         | 
| 312 | 
            +
                  DocWithRemovedKey._validate_callbacks.should be_empty
         | 
| 313 | 
            +
                end
         | 
| 314 | 
            +
              end
         | 
| 315 | 
            +
             | 
| 316 | 
            +
              describe "removing keys in the presence of a validation method" do
         | 
| 317 | 
            +
                DocWithRemovedValidator = Doc do
         | 
| 318 | 
            +
                  key :something
         | 
| 319 | 
            +
                  validate :something_valid?
         | 
| 320 | 
            +
                  remove_key :something
         | 
| 321 | 
            +
             | 
| 322 | 
            +
                  def something_valid?; true; end
         | 
| 323 | 
            +
                end
         | 
| 324 | 
            +
             | 
| 325 | 
            +
                it 'should remove the key' do
         | 
| 326 | 
            +
                  DocWithRemovedKey.keys.should_not have_key "_something"
         | 
| 327 | 
            +
                end
         | 
| 328 | 
            +
             | 
| 329 | 
            +
              end
         | 
| 299 330 | 
             
            end
         | 
    
        data/spec/functional/sci_spec.rb
    CHANGED
    
    | 
            File without changes
         | 
| @@ -0,0 +1,74 @@ | |
| 1 | 
            +
            require 'spec_helper'
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            describe "Stats" do
         | 
| 4 | 
            +
              before(:each) do
         | 
| 5 | 
            +
                class ::Docs
         | 
| 6 | 
            +
                  include MongoMapper::Document
         | 
| 7 | 
            +
                  key   :title, String
         | 
| 8 | 
            +
                  key   :published_at, Time
         | 
| 9 | 
            +
                end
         | 
| 10 | 
            +
             | 
| 11 | 
            +
                Docs.collection.drop
         | 
| 12 | 
            +
              end
         | 
| 13 | 
            +
             | 
| 14 | 
            +
              context "with no documents present" do
         | 
| 15 | 
            +
                it "should return nil" do
         | 
| 16 | 
            +
                  expect(Docs.stats).to eq(nil)
         | 
| 17 | 
            +
                end
         | 
| 18 | 
            +
              end
         | 
| 19 | 
            +
             | 
| 20 | 
            +
              context "with documents present" do
         | 
| 21 | 
            +
                before do
         | 
| 22 | 
            +
                  # Make sure that there is at least one document stored
         | 
| 23 | 
            +
                  Docs.create!
         | 
| 24 | 
            +
                end
         | 
| 25 | 
            +
             | 
| 26 | 
            +
                it "should have the correct count" do
         | 
| 27 | 
            +
                  expect(Docs.stats.count).to eq(Docs.collection.stats['count'])
         | 
| 28 | 
            +
                end
         | 
| 29 | 
            +
             | 
| 30 | 
            +
                it "should have the correct namespace" do
         | 
| 31 | 
            +
                  expect(Docs.stats.ns).to eq(Docs.collection.stats['ns'])
         | 
| 32 | 
            +
                end
         | 
| 33 | 
            +
             | 
| 34 | 
            +
                it "should have the correct size" do
         | 
| 35 | 
            +
                  expect(Docs.stats.size).to eq(Docs.collection.stats['size'])
         | 
| 36 | 
            +
                end
         | 
| 37 | 
            +
             | 
| 38 | 
            +
                it "should have the correct storage size" do
         | 
| 39 | 
            +
                  expect(Docs.stats.storage_size).to eq(Docs.collection.stats['storageSize'])
         | 
| 40 | 
            +
                end
         | 
| 41 | 
            +
             | 
| 42 | 
            +
                it "should have the correct average object size" do
         | 
| 43 | 
            +
                  expect(Docs.stats.avg_obj_size).to eq(Docs.collection.stats['avgObjSize'])
         | 
| 44 | 
            +
                end
         | 
| 45 | 
            +
             | 
| 46 | 
            +
                it "should have the correct number of extents" do
         | 
| 47 | 
            +
                  expect(Docs.stats.num_extents).to eq(Docs.collection.stats['numExtents'])
         | 
| 48 | 
            +
                end
         | 
| 49 | 
            +
             | 
| 50 | 
            +
                it "should have the correct number of indexes" do
         | 
| 51 | 
            +
                  expect(Docs.stats.nindexes).to eq(Docs.collection.stats['nindexes'])
         | 
| 52 | 
            +
                end
         | 
| 53 | 
            +
             | 
| 54 | 
            +
                it "should have the correct last extent size" do
         | 
| 55 | 
            +
                  expect(Docs.stats.last_extent_size).to eq(Docs.collection.stats['lastExtentSize'])
         | 
| 56 | 
            +
                end
         | 
| 57 | 
            +
             | 
| 58 | 
            +
                it "should have the correct padding factor" do
         | 
| 59 | 
            +
                  expect(Docs.stats.padding_factor).to eq(Docs.collection.stats['paddingFactor'])
         | 
| 60 | 
            +
                end
         | 
| 61 | 
            +
             | 
| 62 | 
            +
                it "should have the correct system flags" do
         | 
| 63 | 
            +
                  expect(Docs.stats.system_flags).to eq(Docs.collection.stats['systemFlags'])
         | 
| 64 | 
            +
                end
         | 
| 65 | 
            +
             | 
| 66 | 
            +
                it "should have the correct user flags" do
         | 
| 67 | 
            +
                  expect(Docs.stats.user_flags).to eq(Docs.collection.stats['userFlags'])
         | 
| 68 | 
            +
                end
         | 
| 69 | 
            +
             | 
| 70 | 
            +
                it "should have the correct total index size" do
         | 
| 71 | 
            +
                  expect(Docs.stats.total_index_size).to eq(Docs.collection.stats['totalIndexSize'])
         | 
| 72 | 
            +
                end
         | 
| 73 | 
            +
              end
         | 
| 74 | 
            +
            end
         | 
| @@ -0,0 +1,51 @@ | |
| 1 | 
            +
            if defined?(Encoding) && Encoding.default_external != "UTF-8"
         | 
| 2 | 
            +
              Encoding.default_external = "UTF-8"
         | 
| 3 | 
            +
            end
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            describe "The library itself" do
         | 
| 6 | 
            +
              def check_for_tab_characters(filename)
         | 
| 7 | 
            +
                failing_lines = []
         | 
| 8 | 
            +
                File.readlines(filename).each_with_index do |line,number|
         | 
| 9 | 
            +
                  failing_lines << number + 1 if line =~ /\t/
         | 
| 10 | 
            +
                end
         | 
| 11 | 
            +
             | 
| 12 | 
            +
                unless failing_lines.empty?
         | 
| 13 | 
            +
                  "#{filename} has tab characters on lines #{failing_lines.join(', ')}"
         | 
| 14 | 
            +
                end
         | 
| 15 | 
            +
              end
         | 
| 16 | 
            +
             | 
| 17 | 
            +
              def check_for_extra_spaces(filename)
         | 
| 18 | 
            +
                failing_lines = []
         | 
| 19 | 
            +
                File.readlines(filename).each_with_index do |line,number|
         | 
| 20 | 
            +
                  next if line =~ /^\s+#.*\s+\n$/
         | 
| 21 | 
            +
                  failing_lines << number + 1 if line =~ /\s+\n$/
         | 
| 22 | 
            +
                end
         | 
| 23 | 
            +
             | 
| 24 | 
            +
                unless failing_lines.empty?
         | 
| 25 | 
            +
                  "#{filename} has spaces on the EOL on lines #{failing_lines.join(', ')}"
         | 
| 26 | 
            +
                end
         | 
| 27 | 
            +
              end
         | 
| 28 | 
            +
             | 
| 29 | 
            +
              RSpec::Matchers.define :be_well_formed do
         | 
| 30 | 
            +
                failure_message_for_should do |actual|
         | 
| 31 | 
            +
                  actual.join("\n")
         | 
| 32 | 
            +
                end
         | 
| 33 | 
            +
             | 
| 34 | 
            +
                match do |actual|
         | 
| 35 | 
            +
                  actual.empty?
         | 
| 36 | 
            +
                end
         | 
| 37 | 
            +
              end
         | 
| 38 | 
            +
             | 
| 39 | 
            +
              it "has no malformed whitespace" do
         | 
| 40 | 
            +
                exempt = /\.gitmodules|\.marshal|fixtures|vendor|ssl_certs|kill|LICENSE/
         | 
| 41 | 
            +
                error_messages = []
         | 
| 42 | 
            +
                Dir.chdir(File.expand_path("../..", __FILE__)) do
         | 
| 43 | 
            +
                  `git ls-files`.split("\n").each do |filename|
         | 
| 44 | 
            +
                    next if filename =~ exempt
         | 
| 45 | 
            +
                    error_messages << check_for_tab_characters(filename)
         | 
| 46 | 
            +
                    error_messages << check_for_extra_spaces(filename)
         | 
| 47 | 
            +
                  end
         | 
| 48 | 
            +
                end
         | 
| 49 | 
            +
                expect(error_messages.compact).to be_well_formed
         | 
| 50 | 
            +
              end
         | 
| 51 | 
            +
            end
         | 
| @@ -96,5 +96,10 @@ describe "Proxy" do | |
| 96 96 | 
             
                it "should not work if neither the proxy or target respond to method" do
         | 
| 97 97 | 
             
                  lambda { @proxy.send(:gsub) }.should raise_error
         | 
| 98 98 | 
             
                end
         | 
| 99 | 
            +
             | 
| 100 | 
            +
                it "should work if a proc is passed" do
         | 
| 101 | 
            +
                  p = Proc.new {|x| x+1}
         | 
| 102 | 
            +
                  @proxy.send(:collect, &p).should == [2,3]
         | 
| 103 | 
            +
                end
         | 
| 99 104 | 
             
              end
         | 
| 100 105 | 
             
            end
         | 
| @@ -391,4 +391,28 @@ describe "Support" do | |
| 391 391 | 
             
                  end
         | 
| 392 392 | 
             
                end
         | 
| 393 393 | 
             
              end
         | 
| 394 | 
            +
             | 
| 395 | 
            +
              context "Symbol.to_mongo" do
         | 
| 396 | 
            +
                it "should convert value to_sym" do
         | 
| 397 | 
            +
                  Symbol.to_mongo('asdfasdfasdf').should == :asdfasdfasdf
         | 
| 398 | 
            +
                end
         | 
| 399 | 
            +
             | 
| 400 | 
            +
                it "should convert string if not string" do
         | 
| 401 | 
            +
                  Symbol.to_mongo(123).should == :'123'
         | 
| 402 | 
            +
                end
         | 
| 403 | 
            +
             | 
| 404 | 
            +
                it "should return nil for nil" do
         | 
| 405 | 
            +
                  Symbol.to_mongo(nil).should be_nil
         | 
| 406 | 
            +
                end
         | 
| 407 | 
            +
              end
         | 
| 408 | 
            +
             | 
| 409 | 
            +
              context "Symbol.from_mongo" do
         | 
| 410 | 
            +
                it "should convert value to_sym" do
         | 
| 411 | 
            +
                  Symbol.from_mongo(:asdfasdfasdf).should == :asdfasdfasdf
         | 
| 412 | 
            +
                end
         | 
| 413 | 
            +
             | 
| 414 | 
            +
                it "should return nil for nil" do
         | 
| 415 | 
            +
                  Symbol.from_mongo(nil).should be_nil
         | 
| 416 | 
            +
                end
         | 
| 417 | 
            +
              end
         | 
| 394 418 | 
             
            end
         | 
    
        data/spec/unit/key_spec.rb
    CHANGED
    
    | 
            File without changes
         | 
| 
            File without changes
         | 
    
        data/spec/unit/rails_spec.rb
    CHANGED
    
    | @@ -66,6 +66,11 @@ describe "Rails integration" do | |
| 66 66 | 
             
                    @klass.new(:bar => 'Setting Foo').foo.should == 'Setting Foo'
         | 
| 67 67 | 
             
                  end
         | 
| 68 68 |  | 
| 69 | 
            +
                  it "should return the type casted value from write attribute" do
         | 
| 70 | 
            +
                    obj = @klass.new
         | 
| 71 | 
            +
                    obj.write_attribute(:foo, true).should == "true"
         | 
| 72 | 
            +
                  end
         | 
| 73 | 
            +
             | 
| 69 74 | 
             
                  context '#to_param' do
         | 
| 70 75 | 
             
                    it "should be nil if not persisted" do
         | 
| 71 76 | 
             
                      @klass.new.tap do |doc|
         | 
    
        metadata
    CHANGED
    
    | @@ -1,71 +1,71 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification
         | 
| 2 2 | 
             
            name: mongo_mapper
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            -
              version: 0.13. | 
| 4 | 
            +
              version: 0.13.1
         | 
| 5 5 | 
             
            platform: ruby
         | 
| 6 6 | 
             
            authors:
         | 
| 7 7 | 
             
            - John Nunemaker
         | 
| 8 | 
            -
            autorequire:
         | 
| 8 | 
            +
            autorequire: 
         | 
| 9 9 | 
             
            bindir: bin
         | 
| 10 10 | 
             
            cert_chain: []
         | 
| 11 | 
            -
            date: 2014- | 
| 11 | 
            +
            date: 2014-11-18 00:00:00.000000000 Z
         | 
| 12 12 | 
             
            dependencies:
         | 
| 13 13 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 14 14 | 
             
              name: activemodel
         | 
| 15 | 
            -
               | 
| 15 | 
            +
              requirement: !ruby/object:Gem::Requirement
         | 
| 16 16 | 
             
                requirements:
         | 
| 17 17 | 
             
                - - '>='
         | 
| 18 18 | 
             
                  - !ruby/object:Gem::Version
         | 
| 19 19 | 
             
                    version: 3.0.0
         | 
| 20 | 
            -
               | 
| 20 | 
            +
              type: :runtime
         | 
| 21 | 
            +
              prerelease: false
         | 
| 22 | 
            +
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 21 23 | 
             
                requirements:
         | 
| 22 24 | 
             
                - - '>='
         | 
| 23 25 | 
             
                  - !ruby/object:Gem::Version
         | 
| 24 26 | 
             
                    version: 3.0.0
         | 
| 25 | 
            -
              prerelease: false
         | 
| 26 | 
            -
              type: :runtime
         | 
| 27 27 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 28 28 | 
             
              name: activesupport
         | 
| 29 | 
            -
               | 
| 29 | 
            +
              requirement: !ruby/object:Gem::Requirement
         | 
| 30 30 | 
             
                requirements:
         | 
| 31 31 | 
             
                - - '>='
         | 
| 32 32 | 
             
                  - !ruby/object:Gem::Version
         | 
| 33 33 | 
             
                    version: '3.0'
         | 
| 34 | 
            -
               | 
| 34 | 
            +
              type: :runtime
         | 
| 35 | 
            +
              prerelease: false
         | 
| 36 | 
            +
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 35 37 | 
             
                requirements:
         | 
| 36 38 | 
             
                - - '>='
         | 
| 37 39 | 
             
                  - !ruby/object:Gem::Version
         | 
| 38 40 | 
             
                    version: '3.0'
         | 
| 39 | 
            -
              prerelease: false
         | 
| 40 | 
            -
              type: :runtime
         | 
| 41 41 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 42 42 | 
             
              name: plucky
         | 
| 43 | 
            -
               | 
| 43 | 
            +
              requirement: !ruby/object:Gem::Requirement
         | 
| 44 44 | 
             
                requirements:
         | 
| 45 45 | 
             
                - - ~>
         | 
| 46 46 | 
             
                  - !ruby/object:Gem::Version
         | 
| 47 47 | 
             
                    version: 0.6.5
         | 
| 48 | 
            -
               | 
| 48 | 
            +
              type: :runtime
         | 
| 49 | 
            +
              prerelease: false
         | 
| 50 | 
            +
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 49 51 | 
             
                requirements:
         | 
| 50 52 | 
             
                - - ~>
         | 
| 51 53 | 
             
                  - !ruby/object:Gem::Version
         | 
| 52 54 | 
             
                    version: 0.6.5
         | 
| 53 | 
            -
              prerelease: false
         | 
| 54 | 
            -
              type: :runtime
         | 
| 55 55 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 56 56 | 
             
              name: mongo
         | 
| 57 | 
            -
               | 
| 57 | 
            +
              requirement: !ruby/object:Gem::Requirement
         | 
| 58 58 | 
             
                requirements:
         | 
| 59 59 | 
             
                - - ~>
         | 
| 60 60 | 
             
                  - !ruby/object:Gem::Version
         | 
| 61 61 | 
             
                    version: '1.8'
         | 
| 62 | 
            -
               | 
| 62 | 
            +
              type: :runtime
         | 
| 63 | 
            +
              prerelease: false
         | 
| 64 | 
            +
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 63 65 | 
             
                requirements:
         | 
| 64 66 | 
             
                - - ~>
         | 
| 65 67 | 
             
                  - !ruby/object:Gem::Version
         | 
| 66 68 | 
             
                    version: '1.8'
         | 
| 67 | 
            -
              prerelease: false
         | 
| 68 | 
            -
              type: :runtime
         | 
| 69 69 | 
             
            description: MongoMapper is a Object-Document Mapper for Ruby and Rails
         | 
| 70 70 | 
             
            email:
         | 
| 71 71 | 
             
            - nunemaker@gmail.com
         | 
| @@ -112,6 +112,7 @@ files: | |
| 112 112 | 
             
            - lib/mongo_mapper/extensions/ordered_hash.rb
         | 
| 113 113 | 
             
            - lib/mongo_mapper/extensions/set.rb
         | 
| 114 114 | 
             
            - lib/mongo_mapper/extensions/string.rb
         | 
| 115 | 
            +
            - lib/mongo_mapper/extensions/symbol.rb
         | 
| 115 116 | 
             
            - lib/mongo_mapper/extensions/time.rb
         | 
| 116 117 | 
             
            - lib/mongo_mapper/locale/en.yml
         | 
| 117 118 | 
             
            - lib/mongo_mapper/middleware/identity_map.rb
         | 
| @@ -142,6 +143,7 @@ files: | |
| 142 143 | 
             
            - lib/mongo_mapper/plugins/caching.rb
         | 
| 143 144 | 
             
            - lib/mongo_mapper/plugins/callbacks.rb
         | 
| 144 145 | 
             
            - lib/mongo_mapper/plugins/clone.rb
         | 
| 146 | 
            +
            - lib/mongo_mapper/plugins/counter_cache.rb
         | 
| 145 147 | 
             
            - lib/mongo_mapper/plugins/dirty.rb
         | 
| 146 148 | 
             
            - lib/mongo_mapper/plugins/document.rb
         | 
| 147 149 | 
             
            - lib/mongo_mapper/plugins/dumpable.rb
         | 
| @@ -168,6 +170,7 @@ files: | |
| 168 170 | 
             
            - lib/mongo_mapper/plugins/sci.rb
         | 
| 169 171 | 
             
            - lib/mongo_mapper/plugins/scopes.rb
         | 
| 170 172 | 
             
            - lib/mongo_mapper/plugins/serialization.rb
         | 
| 173 | 
            +
            - lib/mongo_mapper/plugins/stats.rb
         | 
| 171 174 | 
             
            - lib/mongo_mapper/plugins/timestamps.rb
         | 
| 172 175 | 
             
            - lib/mongo_mapper/plugins/touch.rb
         | 
| 173 176 | 
             
            - lib/mongo_mapper/plugins/userstamps.rb
         | 
| @@ -198,6 +201,7 @@ files: | |
| 198 201 | 
             
            - spec/functional/binary_spec.rb
         | 
| 199 202 | 
             
            - spec/functional/caching_spec.rb
         | 
| 200 203 | 
             
            - spec/functional/callbacks_spec.rb
         | 
| 204 | 
            +
            - spec/functional/counter_cache_spec.rb
         | 
| 201 205 | 
             
            - spec/functional/dirty_spec.rb
         | 
| 202 206 | 
             
            - spec/functional/document_spec.rb
         | 
| 203 207 | 
             
            - spec/functional/dumpable_spec.rb
         | 
| @@ -217,10 +221,12 @@ files: | |
| 217 221 | 
             
            - spec/functional/safe_spec.rb
         | 
| 218 222 | 
             
            - spec/functional/sci_spec.rb
         | 
| 219 223 | 
             
            - spec/functional/scopes_spec.rb
         | 
| 224 | 
            +
            - spec/functional/stats_spec.rb
         | 
| 220 225 | 
             
            - spec/functional/timestamps_spec.rb
         | 
| 221 226 | 
             
            - spec/functional/touch_spec.rb
         | 
| 222 227 | 
             
            - spec/functional/userstamps_spec.rb
         | 
| 223 228 | 
             
            - spec/functional/validations_spec.rb
         | 
| 229 | 
            +
            - spec/quality_spec.rb
         | 
| 224 230 | 
             
            - spec/spec_helper.rb
         | 
| 225 231 | 
             
            - spec/support/matchers.rb
         | 
| 226 232 | 
             
            - spec/support/models.rb
         | 
| @@ -258,7 +264,7 @@ homepage: http://mongomapper.com | |
| 258 264 | 
             
            licenses:
         | 
| 259 265 | 
             
            - MIT
         | 
| 260 266 | 
             
            metadata: {}
         | 
| 261 | 
            -
            post_install_message:
         | 
| 267 | 
            +
            post_install_message: 
         | 
| 262 268 | 
             
            rdoc_options: []
         | 
| 263 269 | 
             
            require_paths:
         | 
| 264 270 | 
             
            - lib
         | 
| @@ -273,9 +279,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement | |
| 273 279 | 
             
                - !ruby/object:Gem::Version
         | 
| 274 280 | 
             
                  version: '0'
         | 
| 275 281 | 
             
            requirements: []
         | 
| 276 | 
            -
            rubyforge_project:
         | 
| 282 | 
            +
            rubyforge_project: 
         | 
| 277 283 | 
             
            rubygems_version: 2.2.2
         | 
| 278 | 
            -
            signing_key:
         | 
| 284 | 
            +
            signing_key: 
         | 
| 279 285 | 
             
            specification_version: 4
         | 
| 280 286 | 
             
            summary: A Ruby Object Mapper for Mongo
         | 
| 281 287 | 
             
            test_files: []
         |