samlown-couchrest 0.37.2 → 1.0.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/README.md +10 -4
 - data/Rakefile +1 -1
 - data/history.txt +8 -0
 - data/lib/couchrest.rb +27 -49
 - data/lib/couchrest/{core/database.rb → database.rb} +6 -11
 - data/lib/couchrest/{core/design.rb → design.rb} +2 -2
 - data/lib/couchrest/{core/document.rb → document.rb} +1 -1
 - data/lib/couchrest/helper/attachments.rb +29 -0
 - data/lib/couchrest/middlewares/logger.rb +3 -3
 - data/lib/couchrest/monkeypatches.rb +1 -71
 - data/lib/couchrest/{core/response.rb → response.rb} +0 -0
 - data/lib/couchrest/{core/rest_api.rb → rest_api.rb} +9 -6
 - data/lib/couchrest/{core/server.rb → server.rb} +0 -0
 - data/spec/couchrest/{core/couchrest_spec.rb → couchrest_spec.rb} +16 -3
 - data/spec/couchrest/{core/database_spec.rb → database_spec.rb} +2 -2
 - data/spec/couchrest/{core/design_spec.rb → design_spec.rb} +2 -2
 - data/spec/couchrest/{core/document_spec.rb → document_spec.rb} +1 -1
 - data/spec/couchrest/{core/server_spec.rb → server_spec.rb} +2 -2
 - data/spec/spec.opts +0 -1
 - data/spec/spec_helper.rb +0 -4
 - metadata +24 -113
 - data/couchrest.gemspec +0 -183
 - data/examples/model/example.rb +0 -144
 - data/lib/couchrest/core/adapters/restclient.rb +0 -35
 - data/lib/couchrest/core/http_abstraction.rb +0 -48
 - data/lib/couchrest/core/view.rb +0 -4
 - data/lib/couchrest/mixins.rb +0 -4
 - data/lib/couchrest/mixins/attachments.rb +0 -31
 - data/lib/couchrest/mixins/attribute_protection.rb +0 -74
 - data/lib/couchrest/mixins/callbacks.rb +0 -532
 - data/lib/couchrest/mixins/class_proxy.rb +0 -124
 - data/lib/couchrest/mixins/collection.rb +0 -260
 - data/lib/couchrest/mixins/design_doc.rb +0 -103
 - data/lib/couchrest/mixins/document_queries.rb +0 -80
 - data/lib/couchrest/mixins/extended_attachments.rb +0 -70
 - data/lib/couchrest/mixins/extended_document_mixins.rb +0 -9
 - data/lib/couchrest/mixins/properties.rb +0 -154
 - data/lib/couchrest/mixins/validation.rb +0 -246
 - data/lib/couchrest/mixins/views.rb +0 -173
 - data/lib/couchrest/more/casted_array.rb +0 -25
 - data/lib/couchrest/more/casted_model.rb +0 -58
 - data/lib/couchrest/more/extended_document.rb +0 -310
 - data/lib/couchrest/more/property.rb +0 -50
 - data/lib/couchrest/more/typecast.rb +0 -175
 - data/lib/couchrest/support/blank.rb +0 -42
 - data/lib/couchrest/support/rails.rb +0 -42
 - data/lib/couchrest/validation/auto_validate.rb +0 -157
 - data/lib/couchrest/validation/contextual_validators.rb +0 -78
 - data/lib/couchrest/validation/validation_errors.rb +0 -125
 - data/lib/couchrest/validation/validators/absent_field_validator.rb +0 -74
 - data/lib/couchrest/validation/validators/confirmation_validator.rb +0 -107
 - data/lib/couchrest/validation/validators/format_validator.rb +0 -122
 - data/lib/couchrest/validation/validators/formats/email.rb +0 -66
 - data/lib/couchrest/validation/validators/formats/url.rb +0 -43
 - data/lib/couchrest/validation/validators/generic_validator.rb +0 -120
 - data/lib/couchrest/validation/validators/length_validator.rb +0 -139
 - data/lib/couchrest/validation/validators/method_validator.rb +0 -89
 - data/lib/couchrest/validation/validators/numeric_validator.rb +0 -109
 - data/lib/couchrest/validation/validators/required_field_validator.rb +0 -114
 - data/spec/couchrest/more/attribute_protection_spec.rb +0 -150
 - data/spec/couchrest/more/casted_extended_doc_spec.rb +0 -79
 - data/spec/couchrest/more/casted_model_spec.rb +0 -406
 - data/spec/couchrest/more/extended_doc_attachment_spec.rb +0 -135
 - data/spec/couchrest/more/extended_doc_inherited_spec.rb +0 -40
 - data/spec/couchrest/more/extended_doc_spec.rb +0 -808
 - data/spec/couchrest/more/extended_doc_subclass_spec.rb +0 -98
 - data/spec/couchrest/more/extended_doc_view_spec.rb +0 -462
 - data/spec/couchrest/more/property_spec.rb +0 -628
 - data/spec/fixtures/more/article.rb +0 -35
 - data/spec/fixtures/more/card.rb +0 -22
 - data/spec/fixtures/more/cat.rb +0 -20
 - data/spec/fixtures/more/course.rb +0 -22
 - data/spec/fixtures/more/event.rb +0 -8
 - data/spec/fixtures/more/invoice.rb +0 -17
 - data/spec/fixtures/more/person.rb +0 -9
 - data/spec/fixtures/more/question.rb +0 -6
 - data/spec/fixtures/more/service.rb +0 -12
 - data/spec/fixtures/more/user.rb +0 -22
 
| 
         @@ -1,80 +0,0 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            module CouchRest
         
     | 
| 
       2 
     | 
    
         
            -
              module Mixins
         
     | 
| 
       3 
     | 
    
         
            -
                module DocumentQueries
         
     | 
| 
       4 
     | 
    
         
            -
                  
         
     | 
| 
       5 
     | 
    
         
            -
                  def self.included(base)
         
     | 
| 
       6 
     | 
    
         
            -
                    base.extend(ClassMethods)
         
     | 
| 
       7 
     | 
    
         
            -
                  end
         
     | 
| 
       8 
     | 
    
         
            -
                  
         
     | 
| 
       9 
     | 
    
         
            -
                  module ClassMethods
         
     | 
| 
       10 
     | 
    
         
            -
                    
         
     | 
| 
       11 
     | 
    
         
            -
                    # Load all documents that have the "couchrest-type" field equal to the
         
     | 
| 
       12 
     | 
    
         
            -
                    # name of the current class. Take the standard set of
         
     | 
| 
       13 
     | 
    
         
            -
                    # CouchRest::Database#view options.
         
     | 
| 
       14 
     | 
    
         
            -
                    def all(opts = {}, &block)
         
     | 
| 
       15 
     | 
    
         
            -
                      view(:all, opts, &block)
         
     | 
| 
       16 
     | 
    
         
            -
                    end
         
     | 
| 
       17 
     | 
    
         
            -
                    
         
     | 
| 
       18 
     | 
    
         
            -
                    # Returns the number of documents that have the "couchrest-type" field
         
     | 
| 
       19 
     | 
    
         
            -
                    # equal to the name of the current class. Takes the standard set of 
         
     | 
| 
       20 
     | 
    
         
            -
                    # CouchRest::Database#view options
         
     | 
| 
       21 
     | 
    
         
            -
                    def count(opts = {}, &block)
         
     | 
| 
       22 
     | 
    
         
            -
                      all({:raw => true, :limit => 0}.merge(opts), &block)['total_rows']
         
     | 
| 
       23 
     | 
    
         
            -
                    end
         
     | 
| 
       24 
     | 
    
         
            -
                    
         
     | 
| 
       25 
     | 
    
         
            -
                    # Load the first document that have the "couchrest-type" field equal to
         
     | 
| 
       26 
     | 
    
         
            -
                    # the name of the current class.
         
     | 
| 
       27 
     | 
    
         
            -
                    #
         
     | 
| 
       28 
     | 
    
         
            -
                    # ==== Returns
         
     | 
| 
       29 
     | 
    
         
            -
                    # Object:: The first object instance available
         
     | 
| 
       30 
     | 
    
         
            -
                    # or
         
     | 
| 
       31 
     | 
    
         
            -
                    # Nil:: if no instances available
         
     | 
| 
       32 
     | 
    
         
            -
                    #
         
     | 
| 
       33 
     | 
    
         
            -
                    # ==== Parameters
         
     | 
| 
       34 
     | 
    
         
            -
                    # opts<Hash>::
         
     | 
| 
       35 
     | 
    
         
            -
                    # View options, see <tt>CouchRest::Database#view</tt> options for more info.
         
     | 
| 
       36 
     | 
    
         
            -
                    def first(opts = {})
         
     | 
| 
       37 
     | 
    
         
            -
                      first_instance = self.all(opts.merge!(:limit => 1))
         
     | 
| 
       38 
     | 
    
         
            -
                      first_instance.empty? ? nil : first_instance.first
         
     | 
| 
       39 
     | 
    
         
            -
                    end
         
     | 
| 
       40 
     | 
    
         
            -
                    
         
     | 
| 
       41 
     | 
    
         
            -
                    # Load a document from the database by id
         
     | 
| 
       42 
     | 
    
         
            -
                    # No exceptions will be raised if the document isn't found
         
     | 
| 
       43 
     | 
    
         
            -
                    #
         
     | 
| 
       44 
     | 
    
         
            -
                    # ==== Returns
         
     | 
| 
       45 
     | 
    
         
            -
                    # Object:: if the document was found
         
     | 
| 
       46 
     | 
    
         
            -
                    # or
         
     | 
| 
       47 
     | 
    
         
            -
                    # Nil::
         
     | 
| 
       48 
     | 
    
         
            -
                    # 
         
     | 
| 
       49 
     | 
    
         
            -
                    # === Parameters
         
     | 
| 
       50 
     | 
    
         
            -
                    # id<String, Integer>:: Document ID
         
     | 
| 
       51 
     | 
    
         
            -
                    # db<Database>:: optional option to pass a custom database to use
         
     | 
| 
       52 
     | 
    
         
            -
                    def get(id, db = database)
         
     | 
| 
       53 
     | 
    
         
            -
                      begin
         
     | 
| 
       54 
     | 
    
         
            -
                        get!(id, db)
         
     | 
| 
       55 
     | 
    
         
            -
                      rescue
         
     | 
| 
       56 
     | 
    
         
            -
                        nil
         
     | 
| 
       57 
     | 
    
         
            -
                      end
         
     | 
| 
       58 
     | 
    
         
            -
                    end
         
     | 
| 
       59 
     | 
    
         
            -
                    
         
     | 
| 
       60 
     | 
    
         
            -
                    # Load a document from the database by id
         
     | 
| 
       61 
     | 
    
         
            -
                    # An exception will be raised if the document isn't found
         
     | 
| 
       62 
     | 
    
         
            -
                    #
         
     | 
| 
       63 
     | 
    
         
            -
                    # ==== Returns
         
     | 
| 
       64 
     | 
    
         
            -
                    # Object:: if the document was found
         
     | 
| 
       65 
     | 
    
         
            -
                    # or
         
     | 
| 
       66 
     | 
    
         
            -
                    # Exception
         
     | 
| 
       67 
     | 
    
         
            -
                    # 
         
     | 
| 
       68 
     | 
    
         
            -
                    # === Parameters
         
     | 
| 
       69 
     | 
    
         
            -
                    # id<String, Integer>:: Document ID
         
     | 
| 
       70 
     | 
    
         
            -
                    # db<Database>:: optional option to pass a custom database to use
         
     | 
| 
       71 
     | 
    
         
            -
                    def get!(id, db = database)
         
     | 
| 
       72 
     | 
    
         
            -
                      doc = db.get id
         
     | 
| 
       73 
     | 
    
         
            -
                      create_from_database(doc)
         
     | 
| 
       74 
     | 
    
         
            -
                    end
         
     | 
| 
       75 
     | 
    
         
            -
                    
         
     | 
| 
       76 
     | 
    
         
            -
                  end
         
     | 
| 
       77 
     | 
    
         
            -
                  
         
     | 
| 
       78 
     | 
    
         
            -
                end
         
     | 
| 
       79 
     | 
    
         
            -
              end
         
     | 
| 
       80 
     | 
    
         
            -
            end
         
     | 
| 
         @@ -1,70 +0,0 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            module CouchRest
         
     | 
| 
       2 
     | 
    
         
            -
              module Mixins
         
     | 
| 
       3 
     | 
    
         
            -
                module ExtendedAttachments
         
     | 
| 
       4 
     | 
    
         
            -
             
     | 
| 
       5 
     | 
    
         
            -
                  # creates a file attachment to the current doc
         
     | 
| 
       6 
     | 
    
         
            -
                  def create_attachment(args={})
         
     | 
| 
       7 
     | 
    
         
            -
                    raise ArgumentError unless args[:file] && args[:name]
         
     | 
| 
       8 
     | 
    
         
            -
                    return if has_attachment?(args[:name])
         
     | 
| 
       9 
     | 
    
         
            -
                    self['_attachments'] ||= {}
         
     | 
| 
       10 
     | 
    
         
            -
                    set_attachment_attr(args)
         
     | 
| 
       11 
     | 
    
         
            -
                  rescue ArgumentError => e
         
     | 
| 
       12 
     | 
    
         
            -
                    raise ArgumentError, 'You must specify :file and :name'
         
     | 
| 
       13 
     | 
    
         
            -
                  end
         
     | 
| 
       14 
     | 
    
         
            -
             
     | 
| 
       15 
     | 
    
         
            -
                  # reads the data from an attachment
         
     | 
| 
       16 
     | 
    
         
            -
                  def read_attachment(attachment_name)
         
     | 
| 
       17 
     | 
    
         
            -
                    database.fetch_attachment(self, attachment_name)
         
     | 
| 
       18 
     | 
    
         
            -
                  end
         
     | 
| 
       19 
     | 
    
         
            -
             
     | 
| 
       20 
     | 
    
         
            -
                  # modifies a file attachment on the current doc
         
     | 
| 
       21 
     | 
    
         
            -
                  def update_attachment(args={})
         
     | 
| 
       22 
     | 
    
         
            -
                    raise ArgumentError unless args[:file] && args[:name]
         
     | 
| 
       23 
     | 
    
         
            -
                    return unless has_attachment?(args[:name])
         
     | 
| 
       24 
     | 
    
         
            -
                    delete_attachment(args[:name])
         
     | 
| 
       25 
     | 
    
         
            -
                    set_attachment_attr(args)
         
     | 
| 
       26 
     | 
    
         
            -
                  rescue ArgumentError => e
         
     | 
| 
       27 
     | 
    
         
            -
                    raise ArgumentError, 'You must specify :file and :name'
         
     | 
| 
       28 
     | 
    
         
            -
                  end
         
     | 
| 
       29 
     | 
    
         
            -
             
     | 
| 
       30 
     | 
    
         
            -
                  # deletes a file attachment from the current doc
         
     | 
| 
       31 
     | 
    
         
            -
                  def delete_attachment(attachment_name)
         
     | 
| 
       32 
     | 
    
         
            -
                    return unless self['_attachments']
         
     | 
| 
       33 
     | 
    
         
            -
                    self['_attachments'].delete attachment_name
         
     | 
| 
       34 
     | 
    
         
            -
                  end
         
     | 
| 
       35 
     | 
    
         
            -
             
     | 
| 
       36 
     | 
    
         
            -
                  # returns true if attachment_name exists
         
     | 
| 
       37 
     | 
    
         
            -
                  def has_attachment?(attachment_name)
         
     | 
| 
       38 
     | 
    
         
            -
                    !!(self['_attachments'] && self['_attachments'][attachment_name] && !self['_attachments'][attachment_name].empty?)
         
     | 
| 
       39 
     | 
    
         
            -
                  end
         
     | 
| 
       40 
     | 
    
         
            -
             
     | 
| 
       41 
     | 
    
         
            -
                  # returns URL to fetch the attachment from
         
     | 
| 
       42 
     | 
    
         
            -
                  def attachment_url(attachment_name)
         
     | 
| 
       43 
     | 
    
         
            -
                    return unless has_attachment?(attachment_name)
         
     | 
| 
       44 
     | 
    
         
            -
                    "#{database.root}/#{self.id}/#{attachment_name}"
         
     | 
| 
       45 
     | 
    
         
            -
                  end
         
     | 
| 
       46 
     | 
    
         
            -
                  
         
     | 
| 
       47 
     | 
    
         
            -
                  # returns URI to fetch the attachment from
         
     | 
| 
       48 
     | 
    
         
            -
                  def attachment_uri(attachment_name)
         
     | 
| 
       49 
     | 
    
         
            -
                    return unless has_attachment?(attachment_name)
         
     | 
| 
       50 
     | 
    
         
            -
                    "#{database.uri}/#{self.id}/#{attachment_name}"
         
     | 
| 
       51 
     | 
    
         
            -
                  end
         
     | 
| 
       52 
     | 
    
         
            -
                  
         
     | 
| 
       53 
     | 
    
         
            -
                  private
         
     | 
| 
       54 
     | 
    
         
            -
                  
         
     | 
| 
       55 
     | 
    
         
            -
                    def get_mime_type(file)
         
     | 
| 
       56 
     | 
    
         
            -
                      ::MIME::Types.type_for(file.path).empty? ? 
         
     | 
| 
       57 
     | 
    
         
            -
                        'text\/plain' : MIME::Types.type_for(file.path).first.content_type.gsub(/\//,'\/')
         
     | 
| 
       58 
     | 
    
         
            -
                    end
         
     | 
| 
       59 
     | 
    
         
            -
             
     | 
| 
       60 
     | 
    
         
            -
                    def set_attachment_attr(args)
         
     | 
| 
       61 
     | 
    
         
            -
                      content_type = args[:content_type] ? args[:content_type] : get_mime_type(args[:file])
         
     | 
| 
       62 
     | 
    
         
            -
                      self['_attachments'][args[:name]] = {
         
     | 
| 
       63 
     | 
    
         
            -
                        'content_type' => content_type,
         
     | 
| 
       64 
     | 
    
         
            -
                        'data'         => args[:file].read
         
     | 
| 
       65 
     | 
    
         
            -
                      }
         
     | 
| 
       66 
     | 
    
         
            -
                    end
         
     | 
| 
       67 
     | 
    
         
            -
                  
         
     | 
| 
       68 
     | 
    
         
            -
                end # module ExtendedAttachments
         
     | 
| 
       69 
     | 
    
         
            -
              end
         
     | 
| 
       70 
     | 
    
         
            -
            end
         
     | 
| 
         @@ -1,9 +0,0 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            require File.join(File.dirname(__FILE__), 'properties')
         
     | 
| 
       2 
     | 
    
         
            -
            require File.join(File.dirname(__FILE__), 'document_queries')
         
     | 
| 
       3 
     | 
    
         
            -
            require File.join(File.dirname(__FILE__), 'views')
         
     | 
| 
       4 
     | 
    
         
            -
            require File.join(File.dirname(__FILE__), 'design_doc')
         
     | 
| 
       5 
     | 
    
         
            -
            require File.join(File.dirname(__FILE__), 'validation')
         
     | 
| 
       6 
     | 
    
         
            -
            require File.join(File.dirname(__FILE__), 'extended_attachments')
         
     | 
| 
       7 
     | 
    
         
            -
            require File.join(File.dirname(__FILE__), 'class_proxy')
         
     | 
| 
       8 
     | 
    
         
            -
            require File.join(File.dirname(__FILE__), 'collection')
         
     | 
| 
       9 
     | 
    
         
            -
            require File.join(File.dirname(__FILE__), 'attribute_protection')
         
     | 
| 
         @@ -1,154 +0,0 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            require 'time'
         
     | 
| 
       2 
     | 
    
         
            -
            require File.join(File.dirname(__FILE__), '..', 'more', 'property')
         
     | 
| 
       3 
     | 
    
         
            -
            require File.join(File.dirname(__FILE__), '..', 'more', 'casted_array')
         
     | 
| 
       4 
     | 
    
         
            -
            require File.join(File.dirname(__FILE__), '..', 'more', 'typecast')
         
     | 
| 
       5 
     | 
    
         
            -
             
     | 
| 
       6 
     | 
    
         
            -
            module CouchRest
         
     | 
| 
       7 
     | 
    
         
            -
              module Mixins
         
     | 
| 
       8 
     | 
    
         
            -
                module Properties
         
     | 
| 
       9 
     | 
    
         
            -
                  
         
     | 
| 
       10 
     | 
    
         
            -
                  class IncludeError < StandardError; end
         
     | 
| 
       11 
     | 
    
         
            -
                  
         
     | 
| 
       12 
     | 
    
         
            -
                  include ::CouchRest::More::Typecast
         
     | 
| 
       13 
     | 
    
         
            -
             
     | 
| 
       14 
     | 
    
         
            -
                  def self.included(base)
         
     | 
| 
       15 
     | 
    
         
            -
                    base.class_eval <<-EOS, __FILE__, __LINE__ + 1
         
     | 
| 
       16 
     | 
    
         
            -
                        extlib_inheritable_accessor(:properties) unless self.respond_to?(:properties)
         
     | 
| 
       17 
     | 
    
         
            -
                        self.properties ||= []
         
     | 
| 
       18 
     | 
    
         
            -
                    EOS
         
     | 
| 
       19 
     | 
    
         
            -
                    base.extend(ClassMethods)
         
     | 
| 
       20 
     | 
    
         
            -
                    raise CouchRest::Mixins::Properties::IncludeError, "You can only mixin Properties in a class responding to [] and []=, if you tried to mixin CastedModel, make sure your class inherits from Hash or responds to the proper methods" unless (base.new.respond_to?(:[]) && base.new.respond_to?(:[]=))
         
     | 
| 
       21 
     | 
    
         
            -
                  end
         
     | 
| 
       22 
     | 
    
         
            -
                  
         
     | 
| 
       23 
     | 
    
         
            -
                  def apply_defaults
         
     | 
| 
       24 
     | 
    
         
            -
                    return if self.respond_to?(:new?) && (new? == false)
         
     | 
| 
       25 
     | 
    
         
            -
                    return unless self.class.respond_to?(:properties) 
         
     | 
| 
       26 
     | 
    
         
            -
                    return if self.class.properties.empty?
         
     | 
| 
       27 
     | 
    
         
            -
                    # TODO: cache the default object
         
     | 
| 
       28 
     | 
    
         
            -
                    self.class.properties.each do |property|
         
     | 
| 
       29 
     | 
    
         
            -
                      key = property.name.to_s
         
     | 
| 
       30 
     | 
    
         
            -
                      # let's make sure we have a default
         
     | 
| 
       31 
     | 
    
         
            -
                      unless property.default.nil?
         
     | 
| 
       32 
     | 
    
         
            -
                          if property.default.class == Proc
         
     | 
| 
       33 
     | 
    
         
            -
                            self[key] = property.default.call
         
     | 
| 
       34 
     | 
    
         
            -
                          else
         
     | 
| 
       35 
     | 
    
         
            -
                            self[key] = Marshal.load(Marshal.dump(property.default))
         
     | 
| 
       36 
     | 
    
         
            -
                          end
         
     | 
| 
       37 
     | 
    
         
            -
                        end
         
     | 
| 
       38 
     | 
    
         
            -
                    end
         
     | 
| 
       39 
     | 
    
         
            -
                  end
         
     | 
| 
       40 
     | 
    
         
            -
                  
         
     | 
| 
       41 
     | 
    
         
            -
                  def cast_keys
         
     | 
| 
       42 
     | 
    
         
            -
                    return unless self.class.properties
         
     | 
| 
       43 
     | 
    
         
            -
                    self.class.properties.each do |property|
         
     | 
| 
       44 
     | 
    
         
            -
                      cast_property(property)
         
     | 
| 
       45 
     | 
    
         
            -
                    end
         
     | 
| 
       46 
     | 
    
         
            -
                  end
         
     | 
| 
       47 
     | 
    
         
            -
                  
         
     | 
| 
       48 
     | 
    
         
            -
                  def cast_property(property, assigned=false)
         
     | 
| 
       49 
     | 
    
         
            -
                    return unless property.casted
         
     | 
| 
       50 
     | 
    
         
            -
                    key = self.has_key?(property.name) ? property.name : property.name.to_sym
         
     | 
| 
       51 
     | 
    
         
            -
                    # Don't cast the property unless it has a value
         
     | 
| 
       52 
     | 
    
         
            -
                    return unless self[key]
         
     | 
| 
       53 
     | 
    
         
            -
                    if property.type.is_a?(Array)
         
     | 
| 
       54 
     | 
    
         
            -
                      klass = property.type[0]
         
     | 
| 
       55 
     | 
    
         
            -
                      self[key] = [self[key]] unless self[key].is_a?(Array)
         
     | 
| 
       56 
     | 
    
         
            -
                      arr = self[key].collect do |value|
         
     | 
| 
       57 
     | 
    
         
            -
                        value = typecast_value(value, klass, property.init_method)
         
     | 
| 
       58 
     | 
    
         
            -
                        associate_casted_to_parent(value, assigned)
         
     | 
| 
       59 
     | 
    
         
            -
                        value
         
     | 
| 
       60 
     | 
    
         
            -
                      end
         
     | 
| 
       61 
     | 
    
         
            -
                      # allow casted_by calls to be passed up chain by wrapping in CastedArray
         
     | 
| 
       62 
     | 
    
         
            -
                      self[key] = klass != String ? ::CouchRest::CastedArray.new(arr) : arr
         
     | 
| 
       63 
     | 
    
         
            -
                      self[key].casted_by = self if self[key].respond_to?(:casted_by)
         
     | 
| 
       64 
     | 
    
         
            -
                    else
         
     | 
| 
       65 
     | 
    
         
            -
                      self[key] = typecast_value(self[key], property.type, property.init_method)
         
     | 
| 
       66 
     | 
    
         
            -
                      associate_casted_to_parent(self[key], assigned)
         
     | 
| 
       67 
     | 
    
         
            -
                    end
         
     | 
| 
       68 
     | 
    
         
            -
                  end
         
     | 
| 
       69 
     | 
    
         
            -
                  
         
     | 
| 
       70 
     | 
    
         
            -
                  def associate_casted_to_parent(casted, assigned)
         
     | 
| 
       71 
     | 
    
         
            -
                    casted.casted_by = self if casted.respond_to?(:casted_by)
         
     | 
| 
       72 
     | 
    
         
            -
                    casted.document_saved = true if !assigned && casted.respond_to?(:document_saved)
         
     | 
| 
       73 
     | 
    
         
            -
                  end
         
     | 
| 
       74 
     | 
    
         
            -
                  
         
     | 
| 
       75 
     | 
    
         
            -
                  def cast_property_by_name(property_name)
         
     | 
| 
       76 
     | 
    
         
            -
                    return unless self.class.properties
         
     | 
| 
       77 
     | 
    
         
            -
                    property = self.class.properties.detect{|property| property.name == property_name}
         
     | 
| 
       78 
     | 
    
         
            -
                    return unless property
         
     | 
| 
       79 
     | 
    
         
            -
                    cast_property(property, true)
         
     | 
| 
       80 
     | 
    
         
            -
                  end
         
     | 
| 
       81 
     | 
    
         
            -
                  
         
     | 
| 
       82 
     | 
    
         
            -
                 
         
     | 
| 
       83 
     | 
    
         
            -
                  module ClassMethods
         
     | 
| 
       84 
     | 
    
         
            -
                    
         
     | 
| 
       85 
     | 
    
         
            -
                    def property(name, options={})
         
     | 
| 
       86 
     | 
    
         
            -
                      existing_property = self.properties.find{|p| p.name == name.to_s}
         
     | 
| 
       87 
     | 
    
         
            -
                      if existing_property.nil? || (existing_property.default != options[:default])
         
     | 
| 
       88 
     | 
    
         
            -
                        define_property(name, options)
         
     | 
| 
       89 
     | 
    
         
            -
                      end
         
     | 
| 
       90 
     | 
    
         
            -
                    end
         
     | 
| 
       91 
     | 
    
         
            -
                    
         
     | 
| 
       92 
     | 
    
         
            -
                    protected
         
     | 
| 
       93 
     | 
    
         
            -
                    
         
     | 
| 
       94 
     | 
    
         
            -
                      # This is not a thread safe operation, if you have to set new properties at runtime
         
     | 
| 
       95 
     | 
    
         
            -
                      # make sure to use a mutex.
         
     | 
| 
       96 
     | 
    
         
            -
                      def define_property(name, options={})
         
     | 
| 
       97 
     | 
    
         
            -
                        # check if this property is going to casted
         
     | 
| 
       98 
     | 
    
         
            -
                        options[:casted] = !!(options[:cast_as] || options[:type])
         
     | 
| 
       99 
     | 
    
         
            -
                        property = CouchRest::Property.new(name, (options.delete(:cast_as) || options.delete(:type)), options)
         
     | 
| 
       100 
     | 
    
         
            -
                        create_property_getter(property) 
         
     | 
| 
       101 
     | 
    
         
            -
                        create_property_setter(property) unless property.read_only == true
         
     | 
| 
       102 
     | 
    
         
            -
                        properties << property
         
     | 
| 
       103 
     | 
    
         
            -
                      end
         
     | 
| 
       104 
     | 
    
         
            -
                      
         
     | 
| 
       105 
     | 
    
         
            -
                      # defines the getter for the property (and optional aliases)
         
     | 
| 
       106 
     | 
    
         
            -
                      def create_property_getter(property)
         
     | 
| 
       107 
     | 
    
         
            -
                        # meth = property.name
         
     | 
| 
       108 
     | 
    
         
            -
                        class_eval <<-EOS, __FILE__, __LINE__ + 1
         
     | 
| 
       109 
     | 
    
         
            -
                          def #{property.name}
         
     | 
| 
       110 
     | 
    
         
            -
                            self['#{property.name}']
         
     | 
| 
       111 
     | 
    
         
            -
                          end
         
     | 
| 
       112 
     | 
    
         
            -
                        EOS
         
     | 
| 
       113 
     | 
    
         
            -
             
     | 
| 
       114 
     | 
    
         
            -
                        if property.type == 'boolean'
         
     | 
| 
       115 
     | 
    
         
            -
                          class_eval <<-EOS, __FILE__, __LINE__
         
     | 
| 
       116 
     | 
    
         
            -
                            def #{property.name}?
         
     | 
| 
       117 
     | 
    
         
            -
                              if self['#{property.name}'].nil? || self['#{property.name}'] == false || self['#{property.name}'].to_s.downcase == 'false'
         
     | 
| 
       118 
     | 
    
         
            -
                                false
         
     | 
| 
       119 
     | 
    
         
            -
                              else
         
     | 
| 
       120 
     | 
    
         
            -
                                true
         
     | 
| 
       121 
     | 
    
         
            -
                              end
         
     | 
| 
       122 
     | 
    
         
            -
                            end
         
     | 
| 
       123 
     | 
    
         
            -
                          EOS
         
     | 
| 
       124 
     | 
    
         
            -
                        end
         
     | 
| 
       125 
     | 
    
         
            -
             
     | 
| 
       126 
     | 
    
         
            -
                        if property.alias
         
     | 
| 
       127 
     | 
    
         
            -
                          class_eval <<-EOS, __FILE__, __LINE__ + 1
         
     | 
| 
       128 
     | 
    
         
            -
                            alias #{property.alias.to_sym} #{property.name.to_sym}
         
     | 
| 
       129 
     | 
    
         
            -
                          EOS
         
     | 
| 
       130 
     | 
    
         
            -
                        end
         
     | 
| 
       131 
     | 
    
         
            -
                      end
         
     | 
| 
       132 
     | 
    
         
            -
             
     | 
| 
       133 
     | 
    
         
            -
                      # defines the setter for the property (and optional aliases)
         
     | 
| 
       134 
     | 
    
         
            -
                      def create_property_setter(property)
         
     | 
| 
       135 
     | 
    
         
            -
                        property_name = property.name
         
     | 
| 
       136 
     | 
    
         
            -
                        class_eval <<-EOS
         
     | 
| 
       137 
     | 
    
         
            -
                          def #{property_name}=(value)
         
     | 
| 
       138 
     | 
    
         
            -
                            self['#{property_name}'] = value
         
     | 
| 
       139 
     | 
    
         
            -
                            cast_property_by_name('#{property_name}')
         
     | 
| 
       140 
     | 
    
         
            -
                          end
         
     | 
| 
       141 
     | 
    
         
            -
                        EOS
         
     | 
| 
       142 
     | 
    
         
            -
             
     | 
| 
       143 
     | 
    
         
            -
                        if property.alias
         
     | 
| 
       144 
     | 
    
         
            -
                          class_eval <<-EOS
         
     | 
| 
       145 
     | 
    
         
            -
                            alias #{property.alias.to_sym}= #{property_name.to_sym}=
         
     | 
| 
       146 
     | 
    
         
            -
                          EOS
         
     | 
| 
       147 
     | 
    
         
            -
                        end
         
     | 
| 
       148 
     | 
    
         
            -
                      end
         
     | 
| 
       149 
     | 
    
         
            -
                      
         
     | 
| 
       150 
     | 
    
         
            -
                  end # module ClassMethods
         
     | 
| 
       151 
     | 
    
         
            -
                  
         
     | 
| 
       152 
     | 
    
         
            -
                end
         
     | 
| 
       153 
     | 
    
         
            -
              end
         
     | 
| 
       154 
     | 
    
         
            -
            end
         
     | 
| 
         @@ -1,246 +0,0 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            # Extracted from dm-validations 0.9.10
         
     | 
| 
       2 
     | 
    
         
            -
            #
         
     | 
| 
       3 
     | 
    
         
            -
            # Copyright (c) 2007 Guy van den Berg
         
     | 
| 
       4 
     | 
    
         
            -
            # 
         
     | 
| 
       5 
     | 
    
         
            -
            # Permission is hereby granted, free of charge, to any person obtaining
         
     | 
| 
       6 
     | 
    
         
            -
            # a copy of this software and associated documentation files (the
         
     | 
| 
       7 
     | 
    
         
            -
            # "Software"), to deal in the Software without restriction, including
         
     | 
| 
       8 
     | 
    
         
            -
            # without limitation the rights to use, copy, modify, merge, publish,
         
     | 
| 
       9 
     | 
    
         
            -
            # distribute, sublicense, and/or sell copies of the Software, and to
         
     | 
| 
       10 
     | 
    
         
            -
            # permit persons to whom the Software is furnished to do so, subject to
         
     | 
| 
       11 
     | 
    
         
            -
            # the following conditions:
         
     | 
| 
       12 
     | 
    
         
            -
            # 
         
     | 
| 
       13 
     | 
    
         
            -
            # The above copyright notice and this permission notice shall be
         
     | 
| 
       14 
     | 
    
         
            -
            # included in all copies or substantial portions of the Software.
         
     | 
| 
       15 
     | 
    
         
            -
            # 
         
     | 
| 
       16 
     | 
    
         
            -
            # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
         
     | 
| 
       17 
     | 
    
         
            -
            # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
         
     | 
| 
       18 
     | 
    
         
            -
            # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
         
     | 
| 
       19 
     | 
    
         
            -
            # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
         
     | 
| 
       20 
     | 
    
         
            -
            # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
         
     | 
| 
       21 
     | 
    
         
            -
            # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
         
     | 
| 
       22 
     | 
    
         
            -
            # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
         
     | 
| 
       23 
     | 
    
         
            -
             
     | 
| 
       24 
     | 
    
         
            -
            class Object
         
     | 
| 
       25 
     | 
    
         
            -
              def validatable?
         
     | 
| 
       26 
     | 
    
         
            -
                false
         
     | 
| 
       27 
     | 
    
         
            -
              end
         
     | 
| 
       28 
     | 
    
         
            -
            end
         
     | 
| 
       29 
     | 
    
         
            -
             
     | 
| 
       30 
     | 
    
         
            -
            require 'pathname'
         
     | 
| 
       31 
     | 
    
         
            -
            require File.join(File.dirname(__FILE__), '..', 'support', 'class')
         
     | 
| 
       32 
     | 
    
         
            -
             
     | 
| 
       33 
     | 
    
         
            -
            dir = File.join(Pathname(__FILE__).dirname.expand_path, '..', 'validation')
         
     | 
| 
       34 
     | 
    
         
            -
             
     | 
| 
       35 
     | 
    
         
            -
            require File.join(dir, 'validation_errors')
         
     | 
| 
       36 
     | 
    
         
            -
            require File.join(dir, 'contextual_validators')
         
     | 
| 
       37 
     | 
    
         
            -
            require File.join(dir, 'auto_validate')
         
     | 
| 
       38 
     | 
    
         
            -
             
     | 
| 
       39 
     | 
    
         
            -
            require File.join(dir, 'validators', 'generic_validator')
         
     | 
| 
       40 
     | 
    
         
            -
            require File.join(dir, 'validators', 'required_field_validator')
         
     | 
| 
       41 
     | 
    
         
            -
            require File.join(dir, 'validators', 'absent_field_validator')
         
     | 
| 
       42 
     | 
    
         
            -
            require File.join(dir, 'validators', 'format_validator')
         
     | 
| 
       43 
     | 
    
         
            -
            require File.join(dir, 'validators', 'length_validator')
         
     | 
| 
       44 
     | 
    
         
            -
            require File.join(dir, 'validators', 'numeric_validator')
         
     | 
| 
       45 
     | 
    
         
            -
            require File.join(dir, 'validators', 'method_validator')
         
     | 
| 
       46 
     | 
    
         
            -
            require File.join(dir, 'validators', 'confirmation_validator')
         
     | 
| 
       47 
     | 
    
         
            -
             
     | 
| 
       48 
     | 
    
         
            -
            module CouchRest
         
     | 
| 
       49 
     | 
    
         
            -
              module Validation
         
     | 
| 
       50 
     | 
    
         
            -
                
         
     | 
| 
       51 
     | 
    
         
            -
                def self.included(base)
         
     | 
| 
       52 
     | 
    
         
            -
                  base.extlib_inheritable_accessor(:auto_validation)
         
     | 
| 
       53 
     | 
    
         
            -
                  base.class_eval <<-EOS, __FILE__, __LINE__ + 1
         
     | 
| 
       54 
     | 
    
         
            -
                      # Callbacks
         
     | 
| 
       55 
     | 
    
         
            -
                      define_callbacks :validate
         
     | 
| 
       56 
     | 
    
         
            -
                      
         
     | 
| 
       57 
     | 
    
         
            -
                      # Turn off auto validation by default
         
     | 
| 
       58 
     | 
    
         
            -
                      self.auto_validation ||= false
         
     | 
| 
       59 
     | 
    
         
            -
                      
         
     | 
| 
       60 
     | 
    
         
            -
                      # Force the auto validation for the class properties
         
     | 
| 
       61 
     | 
    
         
            -
                      # This feature is still not fully ported over,
         
     | 
| 
       62 
     | 
    
         
            -
                      # test are lacking, so please use with caution
         
     | 
| 
       63 
     | 
    
         
            -
                      def self.auto_validate!
         
     | 
| 
       64 
     | 
    
         
            -
                        self.auto_validation = true
         
     | 
| 
       65 
     | 
    
         
            -
                      end
         
     | 
| 
       66 
     | 
    
         
            -
                      
         
     | 
| 
       67 
     | 
    
         
            -
                      # share the validations with subclasses
         
     | 
| 
       68 
     | 
    
         
            -
                      def self.inherited(subklass)
         
     | 
| 
       69 
     | 
    
         
            -
                        self.validators.contexts.each do |k, v|
         
     | 
| 
       70 
     | 
    
         
            -
                          subklass.validators.contexts[k] = v.dup
         
     | 
| 
       71 
     | 
    
         
            -
                        end
         
     | 
| 
       72 
     | 
    
         
            -
                        super
         
     | 
| 
       73 
     | 
    
         
            -
                      end
         
     | 
| 
       74 
     | 
    
         
            -
                  EOS
         
     | 
| 
       75 
     | 
    
         
            -
                  
         
     | 
| 
       76 
     | 
    
         
            -
                  base.extend(ClassMethods)
         
     | 
| 
       77 
     | 
    
         
            -
                  base.class_eval <<-EOS, __FILE__, __LINE__ + 1
         
     | 
| 
       78 
     | 
    
         
            -
                    define_callbacks :validate
         
     | 
| 
       79 
     | 
    
         
            -
                    if method_defined?(:_run_save_callbacks)
         
     | 
| 
       80 
     | 
    
         
            -
                      set_callback :save, :before, :check_validations
         
     | 
| 
       81 
     | 
    
         
            -
                    end
         
     | 
| 
       82 
     | 
    
         
            -
                  EOS
         
     | 
| 
       83 
     | 
    
         
            -
                  base.class_eval <<-RUBY_EVAL, __FILE__, __LINE__ + 1
         
     | 
| 
       84 
     | 
    
         
            -
                    def self.define_property(name, options={})
         
     | 
| 
       85 
     | 
    
         
            -
                      super
         
     | 
| 
       86 
     | 
    
         
            -
                      auto_generate_validations(properties.last) if properties && properties.size > 0
         
     | 
| 
       87 
     | 
    
         
            -
                      autovalidation_check = true
         
     | 
| 
       88 
     | 
    
         
            -
                    end
         
     | 
| 
       89 
     | 
    
         
            -
                  RUBY_EVAL
         
     | 
| 
       90 
     | 
    
         
            -
                end
         
     | 
| 
       91 
     | 
    
         
            -
             
     | 
| 
       92 
     | 
    
         
            -
                # Ensures the object is valid for the context provided, and otherwise
         
     | 
| 
       93 
     | 
    
         
            -
                # throws :halt and returns false.
         
     | 
| 
       94 
     | 
    
         
            -
                #
         
     | 
| 
       95 
     | 
    
         
            -
                def check_validations(context = :default)
         
     | 
| 
       96 
     | 
    
         
            -
                  throw(:halt, false) unless context.nil? || valid?(context)
         
     | 
| 
       97 
     | 
    
         
            -
                end
         
     | 
| 
       98 
     | 
    
         
            -
                
         
     | 
| 
       99 
     | 
    
         
            -
                # Return the ValidationErrors
         
     | 
| 
       100 
     | 
    
         
            -
                #
         
     | 
| 
       101 
     | 
    
         
            -
                def errors
         
     | 
| 
       102 
     | 
    
         
            -
                  @errors ||= ValidationErrors.new
         
     | 
| 
       103 
     | 
    
         
            -
                end
         
     | 
| 
       104 
     | 
    
         
            -
             
     | 
| 
       105 
     | 
    
         
            -
                # Mark this resource as validatable. When we validate associations of a
         
     | 
| 
       106 
     | 
    
         
            -
                # resource we can check if they respond to validatable? before trying to
         
     | 
| 
       107 
     | 
    
         
            -
                # recursivly validate them
         
     | 
| 
       108 
     | 
    
         
            -
                #
         
     | 
| 
       109 
     | 
    
         
            -
                def validatable?
         
     | 
| 
       110 
     | 
    
         
            -
                  true
         
     | 
| 
       111 
     | 
    
         
            -
                end
         
     | 
| 
       112 
     | 
    
         
            -
             
     | 
| 
       113 
     | 
    
         
            -
                # Alias for valid?(:default)
         
     | 
| 
       114 
     | 
    
         
            -
                #
         
     | 
| 
       115 
     | 
    
         
            -
                def valid_for_default?
         
     | 
| 
       116 
     | 
    
         
            -
                  valid?(:default)
         
     | 
| 
       117 
     | 
    
         
            -
                end
         
     | 
| 
       118 
     | 
    
         
            -
             
     | 
| 
       119 
     | 
    
         
            -
                # Check if a resource is valid in a given context
         
     | 
| 
       120 
     | 
    
         
            -
                #
         
     | 
| 
       121 
     | 
    
         
            -
                def valid?(context = :default)
         
     | 
| 
       122 
     | 
    
         
            -
                  recursive_valid?(self, context, true)
         
     | 
| 
       123 
     | 
    
         
            -
                end
         
     | 
| 
       124 
     | 
    
         
            -
                
         
     | 
| 
       125 
     | 
    
         
            -
                # checking on casted objects
         
     | 
| 
       126 
     | 
    
         
            -
                def validate_casted_arrays
         
     | 
| 
       127 
     | 
    
         
            -
                  result = true
         
     | 
| 
       128 
     | 
    
         
            -
                  array_casted_properties = self.class.properties.select { |property| property.casted && property.type.instance_of?(Array) }
         
     | 
| 
       129 
     | 
    
         
            -
                  array_casted_properties.each do |property|
         
     | 
| 
       130 
     | 
    
         
            -
                    casted_values = self.send(property.name)
         
     | 
| 
       131 
     | 
    
         
            -
                    next unless casted_values.is_a?(Array) && casted_values.first.respond_to?(:valid?)
         
     | 
| 
       132 
     | 
    
         
            -
                    casted_values.each do |value|
         
     | 
| 
       133 
     | 
    
         
            -
                      result = (result && value.valid?) if value.respond_to?(:valid?)
         
     | 
| 
       134 
     | 
    
         
            -
                    end
         
     | 
| 
       135 
     | 
    
         
            -
                  end
         
     | 
| 
       136 
     | 
    
         
            -
                  result
         
     | 
| 
       137 
     | 
    
         
            -
                end
         
     | 
| 
       138 
     | 
    
         
            -
             
     | 
| 
       139 
     | 
    
         
            -
                # Do recursive validity checking
         
     | 
| 
       140 
     | 
    
         
            -
                #
         
     | 
| 
       141 
     | 
    
         
            -
                def recursive_valid?(target, context, state)
         
     | 
| 
       142 
     | 
    
         
            -
                  valid = state
         
     | 
| 
       143 
     | 
    
         
            -
                  target.each do |key, prop|
         
     | 
| 
       144 
     | 
    
         
            -
                    if prop.is_a?(Array)
         
     | 
| 
       145 
     | 
    
         
            -
                      prop.each do |item|
         
     | 
| 
       146 
     | 
    
         
            -
                        if item.validatable?
         
     | 
| 
       147 
     | 
    
         
            -
                          valid = recursive_valid?(item, context, valid) && valid
         
     | 
| 
       148 
     | 
    
         
            -
                        end
         
     | 
| 
       149 
     | 
    
         
            -
                      end
         
     | 
| 
       150 
     | 
    
         
            -
                    elsif prop.validatable?
         
     | 
| 
       151 
     | 
    
         
            -
                      valid = recursive_valid?(prop, context, valid) && valid
         
     | 
| 
       152 
     | 
    
         
            -
                    end
         
     | 
| 
       153 
     | 
    
         
            -
                  end
         
     | 
| 
       154 
     | 
    
         
            -
                  target._run_validate_callbacks do
         
     | 
| 
       155 
     | 
    
         
            -
                    target.class.validators.execute(context, target) && valid
         
     | 
| 
       156 
     | 
    
         
            -
                  end
         
     | 
| 
       157 
     | 
    
         
            -
                end
         
     | 
| 
       158 
     | 
    
         
            -
             
     | 
| 
       159 
     | 
    
         
            -
             
     | 
| 
       160 
     | 
    
         
            -
                def validation_property_value(name)
         
     | 
| 
       161 
     | 
    
         
            -
                  self.respond_to?(name, true) ? self.send(name) : nil
         
     | 
| 
       162 
     | 
    
         
            -
                end
         
     | 
| 
       163 
     | 
    
         
            -
             
     | 
| 
       164 
     | 
    
         
            -
                # Get the corresponding Object property, if it exists.
         
     | 
| 
       165 
     | 
    
         
            -
                def validation_property(field_name)
         
     | 
| 
       166 
     | 
    
         
            -
                  properties.find{|p| p.name == field_name}
         
     | 
| 
       167 
     | 
    
         
            -
                end
         
     | 
| 
       168 
     | 
    
         
            -
             
     | 
| 
       169 
     | 
    
         
            -
                module ClassMethods
         
     | 
| 
       170 
     | 
    
         
            -
                  include CouchRest::Validation::ValidatesPresent
         
     | 
| 
       171 
     | 
    
         
            -
                  include CouchRest::Validation::ValidatesAbsent
         
     | 
| 
       172 
     | 
    
         
            -
                  include CouchRest::Validation::ValidatesIsConfirmed
         
     | 
| 
       173 
     | 
    
         
            -
                  # include CouchRest::Validation::ValidatesIsPrimitive
         
     | 
| 
       174 
     | 
    
         
            -
                  # include CouchRest::Validation::ValidatesIsAccepted
         
     | 
| 
       175 
     | 
    
         
            -
                  include CouchRest::Validation::ValidatesFormat
         
     | 
| 
       176 
     | 
    
         
            -
                  include CouchRest::Validation::ValidatesLength
         
     | 
| 
       177 
     | 
    
         
            -
                  # include CouchRest::Validation::ValidatesWithin
         
     | 
| 
       178 
     | 
    
         
            -
                  include CouchRest::Validation::ValidatesIsNumber
         
     | 
| 
       179 
     | 
    
         
            -
                  include CouchRest::Validation::ValidatesWithMethod
         
     | 
| 
       180 
     | 
    
         
            -
                  # include CouchRest::Validation::ValidatesWithBlock
         
     | 
| 
       181 
     | 
    
         
            -
                  # include CouchRest::Validation::ValidatesIsUnique
         
     | 
| 
       182 
     | 
    
         
            -
                  include CouchRest::Validation::AutoValidate
         
     | 
| 
       183 
     | 
    
         
            -
                  
         
     | 
| 
       184 
     | 
    
         
            -
                  # Return the set of contextual validators or create a new one
         
     | 
| 
       185 
     | 
    
         
            -
                  #
         
     | 
| 
       186 
     | 
    
         
            -
                  def validators
         
     | 
| 
       187 
     | 
    
         
            -
                    @validations ||= ContextualValidators.new
         
     | 
| 
       188 
     | 
    
         
            -
                  end
         
     | 
| 
       189 
     | 
    
         
            -
                  
         
     | 
| 
       190 
     | 
    
         
            -
                  # Clean up the argument list and return a opts hash, including the
         
     | 
| 
       191 
     | 
    
         
            -
                  # merging of any default opts. Set the context to default if none is
         
     | 
| 
       192 
     | 
    
         
            -
                  # provided. Also allow :context to be aliased to :on, :when & group
         
     | 
| 
       193 
     | 
    
         
            -
                  #
         
     | 
| 
       194 
     | 
    
         
            -
                  def opts_from_validator_args(args, defaults = nil)
         
     | 
| 
       195 
     | 
    
         
            -
                    opts = args.last.kind_of?(Hash) ? args.pop : {}
         
     | 
| 
       196 
     | 
    
         
            -
                    context = :default
         
     | 
| 
       197 
     | 
    
         
            -
                    context = opts[:context] if opts.has_key?(:context)
         
     | 
| 
       198 
     | 
    
         
            -
                    context = opts.delete(:on) if opts.has_key?(:on)
         
     | 
| 
       199 
     | 
    
         
            -
                    context = opts.delete(:when) if opts.has_key?(:when)
         
     | 
| 
       200 
     | 
    
         
            -
                    context = opts.delete(:group) if opts.has_key?(:group)
         
     | 
| 
       201 
     | 
    
         
            -
                    opts[:context] = context
         
     | 
| 
       202 
     | 
    
         
            -
                    opts.merge!(defaults) unless defaults.nil?
         
     | 
| 
       203 
     | 
    
         
            -
                    opts
         
     | 
| 
       204 
     | 
    
         
            -
                  end
         
     | 
| 
       205 
     | 
    
         
            -
                  
         
     | 
| 
       206 
     | 
    
         
            -
                  # Given a new context create an instance method of
         
     | 
| 
       207 
     | 
    
         
            -
                  # valid_for_<context>? which simply calls valid?(context)
         
     | 
| 
       208 
     | 
    
         
            -
                  # if it does not already exist
         
     | 
| 
       209 
     | 
    
         
            -
                  #
         
     | 
| 
       210 
     | 
    
         
            -
                  def create_context_instance_methods(context)
         
     | 
| 
       211 
     | 
    
         
            -
                    name = "valid_for_#{context.to_s}?"           # valid_for_signup?
         
     | 
| 
       212 
     | 
    
         
            -
                    if !self.instance_methods.include?(name)
         
     | 
| 
       213 
     | 
    
         
            -
                      class_eval <<-EOS, __FILE__, __LINE__ + 1
         
     | 
| 
       214 
     | 
    
         
            -
                        def #{name}                               # def valid_for_signup?
         
     | 
| 
       215 
     | 
    
         
            -
                          valid?('#{context.to_s}'.to_sym)        #   valid?('signup'.to_sym)
         
     | 
| 
       216 
     | 
    
         
            -
                        end                                       # end
         
     | 
| 
       217 
     | 
    
         
            -
                      EOS
         
     | 
| 
       218 
     | 
    
         
            -
                    end
         
     | 
| 
       219 
     | 
    
         
            -
                  end
         
     | 
| 
       220 
     | 
    
         
            -
             
     | 
| 
       221 
     | 
    
         
            -
                  # Create a new validator of the given klazz and push it onto the
         
     | 
| 
       222 
     | 
    
         
            -
                  # requested context for each of the attributes in the fields list
         
     | 
| 
       223 
     | 
    
         
            -
                  #
         
     | 
| 
       224 
     | 
    
         
            -
                  def add_validator_to_context(opts, fields, klazz)
         
     | 
| 
       225 
     | 
    
         
            -
                    fields.each do |field|
         
     | 
| 
       226 
     | 
    
         
            -
                      validator = klazz.new(field.to_sym, opts)
         
     | 
| 
       227 
     | 
    
         
            -
                      if opts[:context].is_a?(Symbol)
         
     | 
| 
       228 
     | 
    
         
            -
                        unless validators.context(opts[:context]).include?(validator)
         
     | 
| 
       229 
     | 
    
         
            -
                          validators.context(opts[:context]) << validator
         
     | 
| 
       230 
     | 
    
         
            -
                          create_context_instance_methods(opts[:context])
         
     | 
| 
       231 
     | 
    
         
            -
                        end
         
     | 
| 
       232 
     | 
    
         
            -
                      elsif opts[:context].is_a?(Array)
         
     | 
| 
       233 
     | 
    
         
            -
                        opts[:context].each do |c|
         
     | 
| 
       234 
     | 
    
         
            -
                          unless validators.context(c).include?(validator)
         
     | 
| 
       235 
     | 
    
         
            -
                            validators.context(c) << validator
         
     | 
| 
       236 
     | 
    
         
            -
                            create_context_instance_methods(c)
         
     | 
| 
       237 
     | 
    
         
            -
                          end
         
     | 
| 
       238 
     | 
    
         
            -
                        end
         
     | 
| 
       239 
     | 
    
         
            -
                      end
         
     | 
| 
       240 
     | 
    
         
            -
                    end
         
     | 
| 
       241 
     | 
    
         
            -
                  end
         
     | 
| 
       242 
     | 
    
         
            -
                  
         
     | 
| 
       243 
     | 
    
         
            -
                end # module ClassMethods
         
     | 
| 
       244 
     | 
    
         
            -
              end # module Validation
         
     | 
| 
       245 
     | 
    
         
            -
             
     | 
| 
       246 
     | 
    
         
            -
            end # module CouchRest
         
     |