jnunemaker-mongomapper 0.1.2 → 0.2.0
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.
- data/.gitignore +1 -0
- data/History +13 -0
- data/Rakefile +1 -1
- data/VERSION +1 -1
- data/lib/mongomapper.rb +20 -6
- data/lib/mongomapper/associations.rb +69 -0
- data/lib/mongomapper/associations/array_proxy.rb +6 -0
- data/lib/mongomapper/associations/base.rb +50 -0
- data/lib/mongomapper/associations/belongs_to_proxy.rb +26 -0
- data/lib/mongomapper/associations/has_many_embedded_proxy.rb +19 -0
- data/lib/mongomapper/associations/has_many_proxy.rb +28 -0
- data/lib/mongomapper/associations/polymorphic_belongs_to_proxy.rb +31 -0
- data/lib/mongomapper/associations/proxy.rb +60 -0
- data/lib/mongomapper/callbacks.rb +106 -0
- data/lib/mongomapper/document.rb +83 -54
- data/lib/mongomapper/embedded_document.rb +61 -91
- data/lib/mongomapper/finder_options.rb +37 -35
- data/lib/mongomapper/key.rb +11 -10
- data/lib/mongomapper/observing.rb +90 -0
- data/lib/mongomapper/rails_compatibility.rb +5 -2
- data/lib/mongomapper/save_with_validation.rb +6 -36
- data/lib/mongomapper/validations.rb +47 -0
- data/mongomapper.gemspec +18 -5
- data/test/test_associations.rb +121 -24
- data/test/test_callbacks.rb +3 -6
- data/test/test_document.rb +20 -14
- data/test/test_embedded_document.rb +2 -3
- data/test/test_finder_options.rb +37 -22
- data/test/test_key.rb +30 -30
- data/test/test_observing.rb +101 -0
- data/test/test_rails_compatibility.rb +8 -3
- data/test/test_validations.rb +193 -22
- metadata +16 -3
| @@ -2,6 +2,33 @@ module MongoMapper | |
| 2 2 | 
             
              class FinderOptions
         | 
| 3 3 | 
             
                attr_reader :options
         | 
| 4 4 |  | 
| 5 | 
            +
                def self.to_mongo_criteria(conditions)
         | 
| 6 | 
            +
                  conditions = conditions.dup
         | 
| 7 | 
            +
                  criteria = {}
         | 
| 8 | 
            +
                  conditions.each_pair do |field, value|
         | 
| 9 | 
            +
                    case value
         | 
| 10 | 
            +
                      when Array
         | 
| 11 | 
            +
                        criteria[field] = {'$in' => value}
         | 
| 12 | 
            +
                      when Hash
         | 
| 13 | 
            +
                        criteria[field] = to_mongo_criteria(value)
         | 
| 14 | 
            +
                      else
         | 
| 15 | 
            +
                        criteria[field] = value
         | 
| 16 | 
            +
                    end
         | 
| 17 | 
            +
                  end
         | 
| 18 | 
            +
                  
         | 
| 19 | 
            +
                  criteria
         | 
| 20 | 
            +
                end
         | 
| 21 | 
            +
                
         | 
| 22 | 
            +
                def self.to_mongo_options(options)
         | 
| 23 | 
            +
                  options = options.dup
         | 
| 24 | 
            +
                  {
         | 
| 25 | 
            +
                    :fields => to_mongo_fields(options.delete(:fields) || options.delete(:select)),
         | 
| 26 | 
            +
                    :offset => (options.delete(:offset) || 0).to_i,
         | 
| 27 | 
            +
                    :limit  => (options.delete(:limit) || 0).to_i,
         | 
| 28 | 
            +
                    :sort   => to_mongo_sort(options.delete(:order))
         | 
| 29 | 
            +
                  }
         | 
| 30 | 
            +
                end
         | 
| 31 | 
            +
                
         | 
| 5 32 | 
             
                def initialize(options)
         | 
| 6 33 | 
             
                  raise ArgumentError, "FinderOptions must be a hash" unless options.is_a?(Hash)
         | 
| 7 34 | 
             
                  @options = options.symbolize_keys
         | 
| @@ -9,11 +36,11 @@ module MongoMapper | |
| 9 36 | 
             
                end
         | 
| 10 37 |  | 
| 11 38 | 
             
                def criteria
         | 
| 12 | 
            -
                   | 
| 39 | 
            +
                  self.class.to_mongo_criteria(@conditions)
         | 
| 13 40 | 
             
                end
         | 
| 14 41 |  | 
| 15 42 | 
             
                def options
         | 
| 16 | 
            -
                   | 
| 43 | 
            +
                  self.class.to_mongo_options(@options)
         | 
| 17 44 | 
             
                end
         | 
| 18 45 |  | 
| 19 46 | 
             
                def to_a
         | 
| @@ -21,46 +48,21 @@ module MongoMapper | |
| 21 48 | 
             
                end
         | 
| 22 49 |  | 
| 23 50 | 
             
                private
         | 
| 24 | 
            -
                  def  | 
| 25 | 
            -
                    criteria = {}
         | 
| 26 | 
            -
                    conditions.each_pair do |field, value|
         | 
| 27 | 
            -
                      case value
         | 
| 28 | 
            -
                        when Array
         | 
| 29 | 
            -
                          criteria[field] = {'$in' => value}
         | 
| 30 | 
            -
                        when Hash
         | 
| 31 | 
            -
                          criteria[field] = convert_conditions(value)
         | 
| 32 | 
            -
                        else
         | 
| 33 | 
            -
                          criteria[field] = value
         | 
| 34 | 
            -
                      end
         | 
| 35 | 
            -
                    end
         | 
| 36 | 
            -
                    
         | 
| 37 | 
            -
                    criteria
         | 
| 38 | 
            -
                  end
         | 
| 39 | 
            -
                  
         | 
| 40 | 
            -
                  def convert_options(options)
         | 
| 41 | 
            -
                    {
         | 
| 42 | 
            -
                      :fields => convert_fields(options.delete(:fields) || options.delete(:select)),
         | 
| 43 | 
            -
                      :offset => (options.delete(:offset) || 0).to_i,
         | 
| 44 | 
            -
                      :limit  => (options.delete(:limit) || 0).to_i,
         | 
| 45 | 
            -
                      :sort   => convert_sort(options.delete(:order))
         | 
| 46 | 
            -
                    }
         | 
| 47 | 
            -
                  end
         | 
| 48 | 
            -
                  
         | 
| 49 | 
            -
                  def convert_fields(fields)
         | 
| 51 | 
            +
                  def self.to_mongo_fields(fields)
         | 
| 50 52 | 
             
                    return if fields.blank?
         | 
| 51 | 
            -
             | 
| 53 | 
            +
                  
         | 
| 52 54 | 
             
                    if fields.is_a?(String)
         | 
| 53 55 | 
             
                      fields.split(',').map { |field| field.strip }
         | 
| 54 56 | 
             
                    else
         | 
| 55 57 | 
             
                      fields.flatten.compact
         | 
| 56 58 | 
             
                    end
         | 
| 57 59 | 
             
                  end
         | 
| 58 | 
            -
             | 
| 59 | 
            -
                  def  | 
| 60 | 
            +
                
         | 
| 61 | 
            +
                  def self.to_mongo_sort(sort)
         | 
| 60 62 | 
             
                    return if sort.blank?
         | 
| 61 63 | 
             
                    pieces = sort.split(',')
         | 
| 62 | 
            -
                    pairs  = pieces.map { |s|  | 
| 63 | 
            -
             | 
| 64 | 
            +
                    pairs  = pieces.map { |s| to_mongo_sort_piece(s) }
         | 
| 65 | 
            +
                  
         | 
| 64 66 | 
             
                    hash = OrderedHash.new
         | 
| 65 67 | 
             
                    pairs.each do |pair|
         | 
| 66 68 | 
             
                      field, sort_direction = pair
         | 
| @@ -68,8 +70,8 @@ module MongoMapper | |
| 68 70 | 
             
                    end
         | 
| 69 71 | 
             
                    hash.symbolize_keys
         | 
| 70 72 | 
             
                  end
         | 
| 71 | 
            -
             | 
| 72 | 
            -
                  def  | 
| 73 | 
            +
                
         | 
| 74 | 
            +
                  def self.to_mongo_sort_piece(str)
         | 
| 73 75 | 
             
                    field, direction = str.strip.split(' ')
         | 
| 74 76 | 
             
                    direction ||= 'ASC'
         | 
| 75 77 | 
             
                    direction = direction.upcase == 'ASC' ? 1 : -1
         | 
    
        data/lib/mongomapper/key.rb
    CHANGED
    
    | @@ -1,34 +1,35 @@ | |
| 1 1 | 
             
            class Boolean; end
         | 
| 2 | 
            +
            class Ref; end
         | 
| 2 3 |  | 
| 3 4 | 
             
            module MongoMapper
         | 
| 4 5 | 
             
              class Key
         | 
| 5 6 | 
             
                # DateTime and Date are currently not supported by mongo's bson so just use Time
         | 
| 6 | 
            -
                NativeTypes = [String, Float, Time, Integer, Boolean, Array, Hash]
         | 
| 7 | 
            -
             | 
| 7 | 
            +
                NativeTypes = [String, Float, Time, Integer, Boolean, Array, Hash, Ref]
         | 
| 8 | 
            +
             | 
| 8 9 | 
             
                attr_accessor :name, :type, :options, :default_value
         | 
| 9 | 
            -
             | 
| 10 | 
            +
             | 
| 10 11 | 
             
                def initialize(name, type, options={})
         | 
| 11 12 | 
             
                  @name, @type = name.to_s, type
         | 
| 12 13 | 
             
                  self.options = options.symbolize_keys
         | 
| 13 14 | 
             
                  self.default_value = options.delete(:default)
         | 
| 14 15 | 
             
                end
         | 
| 15 | 
            -
             | 
| 16 | 
            +
             | 
| 16 17 | 
             
                def ==(other)
         | 
| 17 18 | 
             
                  @name == other.name && @type == other.type
         | 
| 18 19 | 
             
                end
         | 
| 19 | 
            -
             | 
| 20 | 
            +
             | 
| 20 21 | 
             
                def set(value)
         | 
| 21 22 | 
             
                  typecast(value)
         | 
| 22 23 | 
             
                end
         | 
| 23 | 
            -
             | 
| 24 | 
            +
             | 
| 24 25 | 
             
                def native?
         | 
| 25 26 | 
             
                  @native ||= NativeTypes.include?(type)
         | 
| 26 27 | 
             
                end
         | 
| 27 | 
            -
             | 
| 28 | 
            +
             | 
| 28 29 | 
             
                def embedded_document?
         | 
| 29 30 | 
             
                  type.ancestors.include?(EmbeddedDocument) && !type.ancestors.include?(Document)
         | 
| 30 31 | 
             
                end
         | 
| 31 | 
            -
             | 
| 32 | 
            +
             | 
| 32 33 | 
             
                def get(value)
         | 
| 33 34 | 
             
                  return default_value if value.nil? && !default_value.nil?
         | 
| 34 35 | 
             
                  if type == Array
         | 
| @@ -39,7 +40,7 @@ module MongoMapper | |
| 39 40 | 
             
                    value
         | 
| 40 41 | 
             
                  end
         | 
| 41 42 | 
             
                end
         | 
| 42 | 
            -
             | 
| 43 | 
            +
             | 
| 43 44 | 
             
                private
         | 
| 44 45 | 
             
                  def typecast(value)
         | 
| 45 46 | 
             
                    return HashWithIndifferentAccess.new(value) if value.is_a?(Hash) && type == Hash
         | 
| @@ -73,7 +74,7 @@ module MongoMapper | |
| 73 74 | 
             
                      value
         | 
| 74 75 | 
             
                    end
         | 
| 75 76 | 
             
                  end
         | 
| 76 | 
            -
             | 
| 77 | 
            +
             | 
| 77 78 | 
             
                  def typecast_embedded_document(value)
         | 
| 78 79 | 
             
                    value.is_a?(type) ? value : type.new(value)
         | 
| 79 80 | 
             
                  end
         | 
| @@ -0,0 +1,90 @@ | |
| 1 | 
            +
            require 'observer'
         | 
| 2 | 
            +
            require 'singleton'
         | 
| 3 | 
            +
            require 'set'
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            module MongoMapper
         | 
| 6 | 
            +
              module Observing #:nodoc:
         | 
| 7 | 
            +
                def self.included(model)
         | 
| 8 | 
            +
                  model.class_eval do
         | 
| 9 | 
            +
                    extend Observable
         | 
| 10 | 
            +
                    extend ClassMethods
         | 
| 11 | 
            +
                  end      
         | 
| 12 | 
            +
                end
         | 
| 13 | 
            +
             | 
| 14 | 
            +
                module ClassMethods
         | 
| 15 | 
            +
                  def observers=(*observers)
         | 
| 16 | 
            +
                    @observers = observers.flatten
         | 
| 17 | 
            +
                  end
         | 
| 18 | 
            +
             | 
| 19 | 
            +
                  def observers
         | 
| 20 | 
            +
                    @observers ||= []
         | 
| 21 | 
            +
                  end
         | 
| 22 | 
            +
             | 
| 23 | 
            +
                  def instantiate_observers
         | 
| 24 | 
            +
                    return if @observers.blank?
         | 
| 25 | 
            +
                    @observers.each do |observer|
         | 
| 26 | 
            +
                      if observer.respond_to?(:to_sym) # Symbol or String
         | 
| 27 | 
            +
                        observer.to_s.camelize.constantize.instance
         | 
| 28 | 
            +
                      elsif observer.respond_to?(:instance)
         | 
| 29 | 
            +
                        observer.instance
         | 
| 30 | 
            +
                      else
         | 
| 31 | 
            +
                        raise ArgumentError, "#{observer} must be a lowercase, underscored class name (or an instance of the class itself) responding to the instance method. Example: Person.observers = :big_brother # calls BigBrother.instance"
         | 
| 32 | 
            +
                      end
         | 
| 33 | 
            +
                    end
         | 
| 34 | 
            +
                  end
         | 
| 35 | 
            +
             | 
| 36 | 
            +
                  protected
         | 
| 37 | 
            +
                    def inherited(subclass)
         | 
| 38 | 
            +
                      super
         | 
| 39 | 
            +
                      changed
         | 
| 40 | 
            +
                      notify_observers :observed_class_inherited, subclass
         | 
| 41 | 
            +
                    end
         | 
| 42 | 
            +
                end
         | 
| 43 | 
            +
              end
         | 
| 44 | 
            +
             | 
| 45 | 
            +
              class Observer
         | 
| 46 | 
            +
                include Singleton
         | 
| 47 | 
            +
             | 
| 48 | 
            +
                class << self
         | 
| 49 | 
            +
                  def observe(*models)
         | 
| 50 | 
            +
                    models.flatten!
         | 
| 51 | 
            +
                    models.collect! { |model| model.is_a?(Symbol) ? model.to_s.camelize.constantize : model }
         | 
| 52 | 
            +
                    define_method(:observed_classes) { Set.new(models) }
         | 
| 53 | 
            +
                  end
         | 
| 54 | 
            +
             | 
| 55 | 
            +
                  def observed_class
         | 
| 56 | 
            +
                    if observed_class_name = name[/(.*)Observer/, 1]
         | 
| 57 | 
            +
                      observed_class_name.constantize
         | 
| 58 | 
            +
                    else
         | 
| 59 | 
            +
                      nil
         | 
| 60 | 
            +
                    end
         | 
| 61 | 
            +
                  end
         | 
| 62 | 
            +
                end
         | 
| 63 | 
            +
             | 
| 64 | 
            +
                def initialize
         | 
| 65 | 
            +
                  Set.new(observed_classes + observed_subclasses).each { |klass| add_observer! klass }
         | 
| 66 | 
            +
                end
         | 
| 67 | 
            +
             | 
| 68 | 
            +
                def update(observed_method, object) #:nodoc:
         | 
| 69 | 
            +
                  send(observed_method, object) if respond_to?(observed_method)
         | 
| 70 | 
            +
                end
         | 
| 71 | 
            +
             | 
| 72 | 
            +
                def observed_class_inherited(subclass) #:nodoc:
         | 
| 73 | 
            +
                  self.class.observe(observed_classes + [subclass])
         | 
| 74 | 
            +
                  add_observer!(subclass)
         | 
| 75 | 
            +
                end
         | 
| 76 | 
            +
             | 
| 77 | 
            +
                protected
         | 
| 78 | 
            +
                  def observed_classes
         | 
| 79 | 
            +
                    Set.new([self.class.observed_class].compact.flatten)
         | 
| 80 | 
            +
                  end
         | 
| 81 | 
            +
                  
         | 
| 82 | 
            +
                  def observed_subclasses
         | 
| 83 | 
            +
                    observed_classes.sum([]) { |klass| klass.send(:subclasses) }
         | 
| 84 | 
            +
                  end
         | 
| 85 | 
            +
                  
         | 
| 86 | 
            +
                  def add_observer!(klass)
         | 
| 87 | 
            +
                    klass.add_observer(self)
         | 
| 88 | 
            +
                  end
         | 
| 89 | 
            +
              end
         | 
| 90 | 
            +
            end
         | 
| @@ -5,14 +5,17 @@ module MongoMapper | |
| 5 5 | 
             
                    alias_method :new_record?, :new?
         | 
| 6 6 | 
             
                    extend ClassMethods
         | 
| 7 7 | 
             
                  end
         | 
| 8 | 
            +
                  class << model
         | 
| 9 | 
            +
                    alias_method :has_many, :many
         | 
| 10 | 
            +
                  end
         | 
| 8 11 | 
             
                end
         | 
| 9 | 
            -
             | 
| 12 | 
            +
             | 
| 10 13 | 
             
                module ClassMethods
         | 
| 11 14 | 
             
                  def column_names
         | 
| 12 15 | 
             
                    keys.keys
         | 
| 13 16 | 
             
                  end
         | 
| 14 17 | 
             
                end
         | 
| 15 | 
            -
             | 
| 18 | 
            +
             | 
| 16 19 | 
             
                def to_param
         | 
| 17 20 | 
             
                  id
         | 
| 18 21 | 
             
                end
         | 
| @@ -2,48 +2,18 @@ module MongoMapper | |
| 2 2 | 
             
              module SaveWithValidation
         | 
| 3 3 | 
             
                def self.included(base)
         | 
| 4 4 | 
             
                  base.class_eval do
         | 
| 5 | 
            -
                    alias_method_chain :valid?, :callbacks
         | 
| 6 5 | 
             
                    alias_method_chain :save, :validation
         | 
| 7 | 
            -
                    
         | 
| 8 | 
            -
                    define_callbacks  :before_validation_on_create,   :before_validation_on_update,
         | 
| 9 | 
            -
                                      :before_validation,             :after_validation,
         | 
| 10 | 
            -
                                      :validate, :validate_on_create, :validate_on_update
         | 
| 6 | 
            +
                    alias_method_chain :save!, :validation
         | 
| 11 7 | 
             
                  end
         | 
| 12 8 | 
             
                end
         | 
| 13 9 |  | 
| 14 | 
            -
                def save!
         | 
| 15 | 
            -
                  save_with_validation || raise(DocumentNotValid.new(self))
         | 
| 16 | 
            -
                end
         | 
| 17 | 
            -
                
         | 
| 18 10 | 
             
                private
         | 
| 19 | 
            -
                  def save_with_validation | 
| 20 | 
            -
                     | 
| 21 | 
            -
                      save_without_validation
         | 
| 22 | 
            -
                    else
         | 
| 23 | 
            -
                      false
         | 
| 24 | 
            -
                    end
         | 
| 11 | 
            +
                  def save_with_validation
         | 
| 12 | 
            +
                    valid? ? save_without_validation : false
         | 
| 25 13 | 
             
                  end
         | 
| 26 | 
            -
             | 
| 27 | 
            -
                  def  | 
| 28 | 
            -
                     | 
| 29 | 
            -
                    
         | 
| 30 | 
            -
                    if new?
         | 
| 31 | 
            -
                      run_callbacks(:before_validation_on_create)
         | 
| 32 | 
            -
                    else
         | 
| 33 | 
            -
                      run_callbacks(:before_validation_on_update)
         | 
| 34 | 
            -
                    end
         | 
| 35 | 
            -
                    
         | 
| 36 | 
            -
                    run_callbacks(:validate)
         | 
| 37 | 
            -
                    
         | 
| 38 | 
            -
                    if new?
         | 
| 39 | 
            -
                      run_callbacks(:validate_on_create)
         | 
| 40 | 
            -
                    else
         | 
| 41 | 
            -
                      run_callbacks(:validate_on_update)
         | 
| 42 | 
            -
                    end
         | 
| 43 | 
            -
                    
         | 
| 44 | 
            -
                    is_valid = valid_without_callbacks?
         | 
| 45 | 
            -
                    run_callbacks(:after_validation) if is_valid
         | 
| 46 | 
            -
                    is_valid 
         | 
| 14 | 
            +
                  
         | 
| 15 | 
            +
                  def save_with_validation!
         | 
| 16 | 
            +
                    valid? ? save_without_validation! : raise(DocumentNotValid.new(self))
         | 
| 47 17 | 
             
                  end
         | 
| 48 18 | 
             
              end  
         | 
| 49 19 | 
             
            end
         | 
| @@ -0,0 +1,47 @@ | |
| 1 | 
            +
            module MongoMapper
         | 
| 2 | 
            +
              module Validations
         | 
| 3 | 
            +
                class ValidatesUniquenessOf < Validatable::ValidationBase
         | 
| 4 | 
            +
                  def valid?(instance)
         | 
| 5 | 
            +
                    # TODO: scope
         | 
| 6 | 
            +
                    doc = instance.class.find(:first, :conditions => {self.attribute => instance[attribute]}, :limit => 1)
         | 
| 7 | 
            +
                    doc.nil? || instance.id == doc.id
         | 
| 8 | 
            +
                  end
         | 
| 9 | 
            +
             | 
| 10 | 
            +
                  def message(instance)
         | 
| 11 | 
            +
                    super || "has already been taken"
         | 
| 12 | 
            +
                  end
         | 
| 13 | 
            +
                end
         | 
| 14 | 
            +
                
         | 
| 15 | 
            +
                class ValidatesExclusionOf < Validatable::ValidationBase
         | 
| 16 | 
            +
                  required_option :within
         | 
| 17 | 
            +
                  
         | 
| 18 | 
            +
                  def valid?(instance)
         | 
| 19 | 
            +
                    value = instance[attribute]
         | 
| 20 | 
            +
                    return true if allow_nil && value.nil?
         | 
| 21 | 
            +
                    return true if allow_blank && value.blank?
         | 
| 22 | 
            +
                    
         | 
| 23 | 
            +
                    !within.include?(instance[attribute])
         | 
| 24 | 
            +
                  end
         | 
| 25 | 
            +
                  
         | 
| 26 | 
            +
                  def message(instance)
         | 
| 27 | 
            +
                    super || "is reserved"
         | 
| 28 | 
            +
                  end
         | 
| 29 | 
            +
                end
         | 
| 30 | 
            +
             | 
| 31 | 
            +
                class ValidatesInclusionOf < Validatable::ValidationBase
         | 
| 32 | 
            +
                  required_option :within
         | 
| 33 | 
            +
                  
         | 
| 34 | 
            +
                  def valid?(instance)
         | 
| 35 | 
            +
                    value = instance[attribute]
         | 
| 36 | 
            +
                    return true if allow_nil && value.nil?
         | 
| 37 | 
            +
                    return true if allow_blank && value.blank?
         | 
| 38 | 
            +
                    
         | 
| 39 | 
            +
                    within.include?(value)
         | 
| 40 | 
            +
                  end
         | 
| 41 | 
            +
                  
         | 
| 42 | 
            +
                  def message(instance)
         | 
| 43 | 
            +
                    super || "is not in the list"
         | 
| 44 | 
            +
                  end
         | 
| 45 | 
            +
                end
         | 
| 46 | 
            +
              end
         | 
| 47 | 
            +
            end
         | 
    
        data/mongomapper.gemspec
    CHANGED
    
    | @@ -2,11 +2,11 @@ | |
| 2 2 |  | 
| 3 3 | 
             
            Gem::Specification.new do |s|
         | 
| 4 4 | 
             
              s.name = %q{mongomapper}
         | 
| 5 | 
            -
              s.version = "0. | 
| 5 | 
            +
              s.version = "0.2.0"
         | 
| 6 6 |  | 
| 7 7 | 
             
              s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
         | 
| 8 8 | 
             
              s.authors = ["John Nunemaker"]
         | 
| 9 | 
            -
              s.date = %q{2009-07- | 
| 9 | 
            +
              s.date = %q{2009-07-07}
         | 
| 10 10 | 
             
              s.email = %q{nunemaker@gmail.com}
         | 
| 11 11 | 
             
              s.extra_rdoc_files = [
         | 
| 12 12 | 
             
                "LICENSE",
         | 
| @@ -20,14 +20,25 @@ Gem::Specification.new do |s| | |
| 20 20 | 
             
                 "Rakefile",
         | 
| 21 21 | 
             
                 "VERSION",
         | 
| 22 22 | 
             
                 "lib/mongomapper.rb",
         | 
| 23 | 
            +
                 "lib/mongomapper/associations.rb",
         | 
| 24 | 
            +
                 "lib/mongomapper/associations/array_proxy.rb",
         | 
| 25 | 
            +
                 "lib/mongomapper/associations/base.rb",
         | 
| 26 | 
            +
                 "lib/mongomapper/associations/belongs_to_proxy.rb",
         | 
| 27 | 
            +
                 "lib/mongomapper/associations/has_many_embedded_proxy.rb",
         | 
| 28 | 
            +
                 "lib/mongomapper/associations/has_many_proxy.rb",
         | 
| 29 | 
            +
                 "lib/mongomapper/associations/polymorphic_belongs_to_proxy.rb",
         | 
| 30 | 
            +
                 "lib/mongomapper/associations/proxy.rb",
         | 
| 31 | 
            +
                 "lib/mongomapper/callbacks.rb",
         | 
| 23 32 | 
             
                 "lib/mongomapper/document.rb",
         | 
| 24 33 | 
             
                 "lib/mongomapper/embedded_document.rb",
         | 
| 25 34 | 
             
                 "lib/mongomapper/finder_options.rb",
         | 
| 26 35 | 
             
                 "lib/mongomapper/key.rb",
         | 
| 36 | 
            +
                 "lib/mongomapper/observing.rb",
         | 
| 27 37 | 
             
                 "lib/mongomapper/rails_compatibility.rb",
         | 
| 28 38 | 
             
                 "lib/mongomapper/save_with_validation.rb",
         | 
| 29 39 | 
             
                 "lib/mongomapper/serialization.rb",
         | 
| 30 40 | 
             
                 "lib/mongomapper/serializers/json_serializer.rb",
         | 
| 41 | 
            +
                 "lib/mongomapper/validations.rb",
         | 
| 31 42 | 
             
                 "mongomapper.gemspec",
         | 
| 32 43 | 
             
                 "test/serializers/test_json_serializer.rb",
         | 
| 33 44 | 
             
                 "test/test_associations.rb",
         | 
| @@ -38,6 +49,7 @@ Gem::Specification.new do |s| | |
| 38 49 | 
             
                 "test/test_helper.rb",
         | 
| 39 50 | 
             
                 "test/test_key.rb",
         | 
| 40 51 | 
             
                 "test/test_mongomapper.rb",
         | 
| 52 | 
            +
                 "test/test_observing.rb",
         | 
| 41 53 | 
             
                 "test/test_rails_compatibility.rb",
         | 
| 42 54 | 
             
                 "test/test_serializations.rb",
         | 
| 43 55 | 
             
                 "test/test_validations.rb"
         | 
| @@ -59,6 +71,7 @@ Gem::Specification.new do |s| | |
| 59 71 | 
             
                 "test/test_helper.rb",
         | 
| 60 72 | 
             
                 "test/test_key.rb",
         | 
| 61 73 | 
             
                 "test/test_mongomapper.rb",
         | 
| 74 | 
            +
                 "test/test_observing.rb",
         | 
| 62 75 | 
             
                 "test/test_rails_compatibility.rb",
         | 
| 63 76 | 
             
                 "test/test_serializations.rb",
         | 
| 64 77 | 
             
                 "test/test_validations.rb"
         | 
| @@ -71,20 +84,20 @@ Gem::Specification.new do |s| | |
| 71 84 | 
             
                if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
         | 
| 72 85 | 
             
                  s.add_runtime_dependency(%q<activesupport>, [">= 0"])
         | 
| 73 86 | 
             
                  s.add_runtime_dependency(%q<mongodb-mongo>, ["= 0.9"])
         | 
| 74 | 
            -
                  s.add_runtime_dependency(%q<jnunemaker-validatable>, ["= 1.7. | 
| 87 | 
            +
                  s.add_runtime_dependency(%q<jnunemaker-validatable>, ["= 1.7.1"])
         | 
| 75 88 | 
             
                  s.add_development_dependency(%q<mocha>, ["= 0.9.4"])
         | 
| 76 89 | 
             
                  s.add_development_dependency(%q<jnunemaker-matchy>, ["= 0.4.0"])
         | 
| 77 90 | 
             
                else
         | 
| 78 91 | 
             
                  s.add_dependency(%q<activesupport>, [">= 0"])
         | 
| 79 92 | 
             
                  s.add_dependency(%q<mongodb-mongo>, ["= 0.9"])
         | 
| 80 | 
            -
                  s.add_dependency(%q<jnunemaker-validatable>, ["= 1.7. | 
| 93 | 
            +
                  s.add_dependency(%q<jnunemaker-validatable>, ["= 1.7.1"])
         | 
| 81 94 | 
             
                  s.add_dependency(%q<mocha>, ["= 0.9.4"])
         | 
| 82 95 | 
             
                  s.add_dependency(%q<jnunemaker-matchy>, ["= 0.4.0"])
         | 
| 83 96 | 
             
                end
         | 
| 84 97 | 
             
              else
         | 
| 85 98 | 
             
                s.add_dependency(%q<activesupport>, [">= 0"])
         | 
| 86 99 | 
             
                s.add_dependency(%q<mongodb-mongo>, ["= 0.9"])
         | 
| 87 | 
            -
                s.add_dependency(%q<jnunemaker-validatable>, ["= 1.7. | 
| 100 | 
            +
                s.add_dependency(%q<jnunemaker-validatable>, ["= 1.7.1"])
         | 
| 88 101 | 
             
                s.add_dependency(%q<mocha>, ["= 0.9.4"])
         | 
| 89 102 | 
             
                s.add_dependency(%q<jnunemaker-matchy>, ["= 0.4.0"])
         | 
| 90 103 | 
             
              end
         |