her 0.5.1 → 0.5.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +8 -8
- data/Gemfile +1 -1
- data/LICENSE +1 -1
- data/README.md +9 -10
- data/lib/her/api.rb +3 -3
- data/lib/her/errors.rb +1 -1
- data/lib/her/model.rb +6 -6
- data/lib/her/model/{relationships.rb → associations.rb} +79 -58
- data/lib/her/model/introspection.rb +1 -1
- data/lib/her/model/nested_attributes.rb +24 -24
- data/lib/her/model/orm.rb +55 -50
- data/lib/her/model/paths.rb +2 -2
- data/lib/her/version.rb +1 -1
- data/spec/model/{relationships_spec.rb → associations_spec.rb} +56 -52
- data/spec/model/nested_attributes_spec.rb +3 -3
- data/spec/model/orm_spec.rb +5 -15
- data/spec/model/paths_spec.rb +3 -3
- metadata +5 -5
    
        checksums.yaml
    CHANGED
    
    | @@ -1,15 +1,15 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            !binary "U0hBMQ==":
         | 
| 3 3 | 
             
              metadata.gz: !binary |-
         | 
| 4 | 
            -
                 | 
| 4 | 
            +
                NDM1MWIwOWZmYThlZjA5YTJlMzdlZDM3MDQzMjg5ZGNlOTVhOGYxMQ==
         | 
| 5 5 | 
             
              data.tar.gz: !binary |-
         | 
| 6 | 
            -
                 | 
| 6 | 
            +
                ODgwMDMwMDM3M2MyZTdjN2YwZDBhMDlhMDJlZTY5MzcwZTVhMjVjNQ==
         | 
| 7 7 | 
             
            !binary "U0hBNTEy":
         | 
| 8 8 | 
             
              metadata.gz: !binary |-
         | 
| 9 | 
            -
                 | 
| 10 | 
            -
                 | 
| 11 | 
            -
                 | 
| 9 | 
            +
                OGIyY2JkM2Y5OTI4NzdmZDk5OTE2ZGM4OWU4ZTM3MTYzOWNhMGRlOWZlNTc4
         | 
| 10 | 
            +
                ZTcxODBmYzMxYjdmNDJkNGFhZDc0NGQzZGE3ODU0NTE4ODliYjQ4MTIyMGJi
         | 
| 11 | 
            +
                NjBjMTE3ZGE1ZDM5Y2QwYWVjNTgwZDQxOGRkNDc0OTRhYzA2YjQ=
         | 
| 12 12 | 
             
              data.tar.gz: !binary |-
         | 
| 13 | 
            -
                 | 
| 14 | 
            -
                 | 
| 15 | 
            -
                 | 
| 13 | 
            +
                M2ZlYmU3ZGE5ZjBkNDkxYjgyZWFlZmM4OWEyYjMxYzYzMmI1ODAyOTFhMmM1
         | 
| 14 | 
            +
                ZDk0ZDA1YWUxODY2NGIzZDEwMTdiODQ5MWJkN2NlYjFlMTc5YjAxZmVkYzY1
         | 
| 15 | 
            +
                NjY3YWY4NGIyNGFkNzMxNmZmY2E2YmJkOTIyNWZjMjU3MjZhNTE=
         | 
    
        data/Gemfile
    CHANGED
    
    | @@ -1,2 +1,2 @@ | |
| 1 | 
            -
            source  | 
| 1 | 
            +
            source "https://rubygems.org"
         | 
| 2 2 | 
             
            gemspec
         | 
    
        data/LICENSE
    CHANGED
    
    | @@ -1,4 +1,4 @@ | |
| 1 | 
            -
            Copyright (c) 2012 Rémi Prévost
         | 
| 1 | 
            +
            Copyright (c) 2012-2013 Rémi Prévost
         | 
| 2 2 |  | 
| 3 3 | 
             
            Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
         | 
| 4 4 |  | 
    
        data/README.md
    CHANGED
    
    | @@ -261,12 +261,12 @@ end | |
| 261 261 |  | 
| 262 262 | 
             
            Here’s a list of several useful features available in Her.
         | 
| 263 263 |  | 
| 264 | 
            -
            ###  | 
| 264 | 
            +
            ### Associations
         | 
| 265 265 |  | 
| 266 | 
            -
            You can define `has_many`, `has_one` and `belongs_to`  | 
| 266 | 
            +
            You can define `has_many`, `has_one` and `belongs_to` associations in your models. The association data is handled in two different ways.
         | 
| 267 267 |  | 
| 268 | 
            -
            1. If Her finds  | 
| 269 | 
            -
            2. If no  | 
| 268 | 
            +
            1. If Her finds association data when parsing a resource, that data will be used to create the associated model objects on the resource.
         | 
| 269 | 
            +
            2. If no association data was included when parsing a resource, calling a method with the same name as the association will fetch the data (providing there’s an HTTP request available for it in the API).
         | 
| 270 270 |  | 
| 271 271 | 
             
            For example:
         | 
| 272 272 |  | 
| @@ -291,7 +291,7 @@ class Organization | |
| 291 291 | 
             
            end
         | 
| 292 292 | 
             
            ```
         | 
| 293 293 |  | 
| 294 | 
            -
            If there’s  | 
| 294 | 
            +
            If there’s association data in the resource, no extra HTTP request is made when calling the `#comments` method and an array of resources is returned:
         | 
| 295 295 |  | 
| 296 296 | 
             
            ```ruby
         | 
| 297 297 | 
             
            @user = User.find(1)
         | 
| @@ -315,23 +315,23 @@ If there’s relationship data in the resource, no extra HTTP request is made wh | |
| 315 315 | 
             
            # #<Organization id=2 name="Bluth Company">
         | 
| 316 316 | 
             
            ```
         | 
| 317 317 |  | 
| 318 | 
            -
            If there’s no  | 
| 318 | 
            +
            If there’s no association data in the resource, Her makes a HTTP request to retrieve the data.
         | 
| 319 319 |  | 
| 320 320 | 
             
            ```ruby
         | 
| 321 321 | 
             
            @user = User.find(1)
         | 
| 322 322 | 
             
            # { :data => { :id => 1, :name => "George Michael Bluth", :organization_id => 2 }}
         | 
| 323 323 |  | 
| 324 | 
            -
            # has_many  | 
| 324 | 
            +
            # has_many association:
         | 
| 325 325 | 
             
            @user.comments
         | 
| 326 326 | 
             
            # GET /users/1/comments
         | 
| 327 327 | 
             
            # [#<Comment id=1>, #<Comment id=2>]
         | 
| 328 328 |  | 
| 329 | 
            -
            # has_one  | 
| 329 | 
            +
            # has_one association:
         | 
| 330 330 | 
             
            @user.role
         | 
| 331 331 | 
             
            # GET /users/1/role
         | 
| 332 332 | 
             
            # #<Role id=1>
         | 
| 333 333 |  | 
| 334 | 
            -
            # belongs_to  | 
| 334 | 
            +
            # belongs_to association:
         | 
| 335 335 | 
             
            @user.organization
         | 
| 336 336 | 
             
            # (the organization id comes from :organization_id, by default)
         | 
| 337 337 | 
             
            # GET /organizations/2
         | 
| @@ -365,7 +365,6 @@ end | |
| 365 365 | 
             
            ### Dirty attributes
         | 
| 366 366 |  | 
| 367 367 | 
             
            Her includes `ActiveModel::Dirty` so you can keep track of the attributes that have changed in an object.
         | 
| 368 | 
            -
            an object, or `#create` on a model class.
         | 
| 369 368 |  | 
| 370 369 | 
             
            ```ruby
         | 
| 371 370 | 
             
            class User
         | 
    
        data/lib/her/api.rb
    CHANGED
    
    | @@ -7,8 +7,8 @@ module Her | |
| 7 7 |  | 
| 8 8 | 
             
                # Setup a default API connection. Accepted arguments and options are the same as {API#setup}.
         | 
| 9 9 | 
             
                def self.setup(attrs={}, &block)
         | 
| 10 | 
            -
                   | 
| 11 | 
            -
                   | 
| 10 | 
            +
                  @default_api = new
         | 
| 11 | 
            +
                  @default_api.setup(attrs, &block)
         | 
| 12 12 | 
             
                end
         | 
| 13 13 |  | 
| 14 14 | 
             
                # Create a new API object. This is useful to create multiple APIs and use them with the `uses_api` method.
         | 
| @@ -103,7 +103,7 @@ module Her | |
| 103 103 | 
             
                private
         | 
| 104 104 | 
             
                # @private
         | 
| 105 105 | 
             
                def self.default_api(attrs={})
         | 
| 106 | 
            -
                  defined?( | 
| 106 | 
            +
                  defined?(@default_api) ? @default_api : nil
         | 
| 107 107 | 
             
                end
         | 
| 108 108 | 
             
              end
         | 
| 109 109 | 
             
            end
         | 
    
        data/lib/her/errors.rb
    CHANGED
    
    
    
        data/lib/her/model.rb
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            require "her/model/base"
         | 
| 2 2 | 
             
            require "her/model/http"
         | 
| 3 3 | 
             
            require "her/model/orm"
         | 
| 4 | 
            -
            require "her/model/ | 
| 4 | 
            +
            require "her/model/associations"
         | 
| 5 5 | 
             
            require "her/model/introspection"
         | 
| 6 6 | 
             
            require "her/model/paths"
         | 
| 7 7 | 
             
            require "her/model/nested_attributes"
         | 
| @@ -25,7 +25,7 @@ module Her | |
| 25 25 | 
             
                include Her::Model::ORM
         | 
| 26 26 | 
             
                include Her::Model::Introspection
         | 
| 27 27 | 
             
                include Her::Model::Paths
         | 
| 28 | 
            -
                include Her::Model:: | 
| 28 | 
            +
                include Her::Model::Associations
         | 
| 29 29 | 
             
                include Her::Model::NestedAttributes
         | 
| 30 30 | 
             
                include ActiveModel::Validations
         | 
| 31 31 | 
             
                include ActiveModel::Conversion
         | 
| @@ -51,18 +51,18 @@ module Her | |
| 51 51 |  | 
| 52 52 | 
             
                # Returns true if attribute_name is
         | 
| 53 53 | 
             
                # * in orm data
         | 
| 54 | 
            -
                # *  | 
| 54 | 
            +
                # * an association
         | 
| 55 55 | 
             
                def has_key?(attribute_name)
         | 
| 56 56 | 
             
                  has_data?(attribute_name) ||
         | 
| 57 | 
            -
                   | 
| 57 | 
            +
                  has_association?(attribute_name)
         | 
| 58 58 | 
             
                end
         | 
| 59 59 |  | 
| 60 60 | 
             
                # Returns
         | 
| 61 61 | 
             
                # * the value of the attribute_nane attribute if it's in orm data
         | 
| 62 | 
            -
                # * the resource/collection corrsponding to attribute_name if it's  | 
| 62 | 
            +
                # * the resource/collection corrsponding to attribute_name if it's an association
         | 
| 63 63 | 
             
                def [](attribute_name)
         | 
| 64 64 | 
             
                  get_data(attribute_name) ||
         | 
| 65 | 
            -
                   | 
| 65 | 
            +
                  get_association(attribute_name)
         | 
| 66 66 | 
             
                end
         | 
| 67 67 | 
             
              end
         | 
| 68 68 | 
             
            end
         | 
| @@ -1,49 +1,55 @@ | |
| 1 1 | 
             
            module Her
         | 
| 2 2 | 
             
              module Model
         | 
| 3 | 
            -
                # This module adds  | 
| 4 | 
            -
                module  | 
| 3 | 
            +
                # This module adds associations to models
         | 
| 4 | 
            +
                module Associations
         | 
| 5 5 | 
             
                  extend ActiveSupport::Concern
         | 
| 6 6 |  | 
| 7 | 
            -
                  # Returns true if the model has a  | 
| 8 | 
            -
                  def  | 
| 9 | 
            -
                     | 
| 10 | 
            -
                     | 
| 7 | 
            +
                  # Returns true if the model has a association_name association, false otherwise.
         | 
| 8 | 
            +
                  def has_association?(association_name)
         | 
| 9 | 
            +
                    associations = self.class.associations.values.flatten.map { |r| r[:name] }
         | 
| 10 | 
            +
                    associations.include?(association_name)
         | 
| 11 11 | 
             
                  end
         | 
| 12 | 
            +
                  alias :has_relationship? :has_association?
         | 
| 12 13 |  | 
| 13 | 
            -
                  # Returns the resource/collection corresponding to the  | 
| 14 | 
            -
                  def  | 
| 15 | 
            -
                    send( | 
| 14 | 
            +
                  # Returns the resource/collection corresponding to the association_name association.
         | 
| 15 | 
            +
                  def get_association(association_name)
         | 
| 16 | 
            +
                    send(association_name) if has_association?(association_name)
         | 
| 16 17 | 
             
                  end
         | 
| 18 | 
            +
                  alias :get_relationship :get_association
         | 
| 17 19 |  | 
| 18 20 | 
             
                  module ClassMethods
         | 
| 19 | 
            -
                    # Return @ | 
| 20 | 
            -
                    # superclass'  | 
| 21 | 
            +
                    # Return @her_associations, lazily initialized with copy of the
         | 
| 22 | 
            +
                    # superclass' her_associations, or an empty hash.
         | 
| 21 23 | 
             
                    #
         | 
| 22 24 | 
             
                    # @private
         | 
| 23 | 
            -
                    def  | 
| 24 | 
            -
                      @ | 
| 25 | 
            -
                        if superclass.respond_to?(: | 
| 26 | 
            -
                          superclass. | 
| 25 | 
            +
                    def associations
         | 
| 26 | 
            +
                      @her_associations ||= begin
         | 
| 27 | 
            +
                        if superclass.respond_to?(:associations)
         | 
| 28 | 
            +
                          superclass.associations.dup
         | 
| 27 29 | 
             
                        else
         | 
| 28 30 | 
             
                          {}
         | 
| 29 31 | 
             
                        end
         | 
| 30 32 | 
             
                      end
         | 
| 31 33 | 
             
                    end
         | 
| 34 | 
            +
                    alias :relationships :associations
         | 
| 32 35 |  | 
| 33 | 
            -
                    # Parse  | 
| 36 | 
            +
                    # Parse associations data after initializing a new object
         | 
| 34 37 | 
             
                    #
         | 
| 35 38 | 
             
                    # @private
         | 
| 36 | 
            -
                    def  | 
| 37 | 
            -
                       | 
| 38 | 
            -
                        definitions.each do | | 
| 39 | 
            -
                           | 
| 40 | 
            -
                          next unless data[ | 
| 41 | 
            -
             | 
| 39 | 
            +
                    def parse_associations(data)
         | 
| 40 | 
            +
                      associations.each_pair do |type, definitions|
         | 
| 41 | 
            +
                        definitions.each do |association|
         | 
| 42 | 
            +
                          data_key = association[:data_key]
         | 
| 43 | 
            +
                          next unless data[data_key]
         | 
| 44 | 
            +
             | 
| 45 | 
            +
                          klass = self.nearby_class(association[:class_name])
         | 
| 46 | 
            +
                          name = association[:name]
         | 
| 47 | 
            +
             | 
| 42 48 | 
             
                          data[name] = case type
         | 
| 43 49 | 
             
                            when :has_many
         | 
| 44 | 
            -
                              Her::Model::ORM.initialize_collection(klass, :data => data[ | 
| 50 | 
            +
                              Her::Model::ORM.initialize_collection(klass, :data => data[data_key])
         | 
| 45 51 | 
             
                            when :has_one, :belongs_to
         | 
| 46 | 
            -
                              klass.new( | 
| 52 | 
            +
                              klass.new(data[data_key])
         | 
| 47 53 | 
             
                            else
         | 
| 48 54 | 
             
                              nil
         | 
| 49 55 | 
             
                          end
         | 
| @@ -52,7 +58,7 @@ module Her | |
| 52 58 | 
             
                      data
         | 
| 53 59 | 
             
                    end
         | 
| 54 60 |  | 
| 55 | 
            -
                    # Define an *has_many*  | 
| 61 | 
            +
                    # Define an *has_many* association.
         | 
| 56 62 | 
             
                    #
         | 
| 57 63 | 
             
                    # @param [Symbol] name The name of the model
         | 
| 58 64 | 
             
                    # @param [Hash] attrs Options (currently not used)
         | 
| @@ -74,34 +80,39 @@ module Her | |
| 74 80 | 
             
                      attrs = {
         | 
| 75 81 | 
             
                        :class_name     => name.to_s.classify,
         | 
| 76 82 | 
             
                        :name           => name,
         | 
| 83 | 
            +
                        :data_key       => name,
         | 
| 77 84 | 
             
                        :path           => "/#{name}",
         | 
| 78 85 | 
             
                        :inverse_of => nil
         | 
| 79 86 | 
             
                      }.merge(attrs)
         | 
| 80 | 
            -
                      ( | 
| 87 | 
            +
                      (associations[:has_many] ||= []) << attrs
         | 
| 81 88 |  | 
| 82 89 | 
             
                      define_method(name) do |*method_attrs|
         | 
| 83 90 | 
             
                        method_attrs = method_attrs[0] || {}
         | 
| 84 91 | 
             
                        klass = self.class.nearby_class(attrs[:class_name])
         | 
| 85 | 
            -
             | 
| 86 | 
            -
             | 
| 87 | 
            -
             | 
| 88 | 
            -
             | 
| 92 | 
            +
             | 
| 93 | 
            +
                        return Her::Collection.new if @attributes.include?(name) && @attributes[name].empty? && method_attrs.empty?
         | 
| 94 | 
            +
             | 
| 95 | 
            +
                        if @attributes[name].blank? || method_attrs.any?
         | 
| 96 | 
            +
                          path = begin
         | 
| 97 | 
            +
                            self.class.build_request_path(@attributes.merge(method_attrs))
         | 
| 98 | 
            +
                          rescue Her::Errors::PathError
         | 
| 99 | 
            +
                            return nil
         | 
| 100 | 
            +
                          end
         | 
| 101 | 
            +
             | 
| 102 | 
            +
                          @attributes[name] = klass.get_collection("#{path}#{attrs[:path]}", method_attrs)
         | 
| 89 103 | 
             
                        end
         | 
| 90 104 |  | 
| 91 | 
            -
                        inverse_of =  | 
| 92 | 
            -
             | 
| 93 | 
            -
             | 
| 94 | 
            -
                                         self.class.name.split('::').last.tableize.singularize
         | 
| 95 | 
            -
                                       end
         | 
| 96 | 
            -
                        @data[name].each do |entry|
         | 
| 105 | 
            +
                        inverse_of = attrs[:inverse_of] || self.class.name.split('::').last.tableize.singularize
         | 
| 106 | 
            +
             | 
| 107 | 
            +
                        @attributes[name].each do |entry|
         | 
| 97 108 | 
             
                          entry.send("#{inverse_of}=", self)
         | 
| 98 109 | 
             
                        end
         | 
| 99 110 |  | 
| 100 | 
            -
                        @ | 
| 111 | 
            +
                        @attributes[name]
         | 
| 101 112 | 
             
                      end
         | 
| 102 113 | 
             
                    end
         | 
| 103 114 |  | 
| 104 | 
            -
                    # Define an *has_one*  | 
| 115 | 
            +
                    # Define an *has_one* association.
         | 
| 105 116 | 
             
                    #
         | 
| 106 117 | 
             
                    # @param [Symbol] name The name of the model
         | 
| 107 118 | 
             
                    # @param [Hash] attrs Options (currently not used)
         | 
| @@ -123,22 +134,32 @@ module Her | |
| 123 134 | 
             
                      attrs = {
         | 
| 124 135 | 
             
                        :class_name => name.to_s.classify,
         | 
| 125 136 | 
             
                        :name => name,
         | 
| 137 | 
            +
                        :data_key => name,
         | 
| 126 138 | 
             
                        :path => "/#{name}"
         | 
| 127 139 | 
             
                      }.merge(attrs)
         | 
| 128 | 
            -
                      ( | 
| 140 | 
            +
                      (associations[:has_one] ||= []) << attrs
         | 
| 129 141 |  | 
| 130 142 | 
             
                      define_method(name) do |*method_attrs|
         | 
| 131 143 | 
             
                        method_attrs = method_attrs[0] || {}
         | 
| 132 144 | 
             
                        klass = self.class.nearby_class(attrs[:class_name])
         | 
| 133 | 
            -
             | 
| 134 | 
            -
             | 
| 135 | 
            -
             | 
| 136 | 
            -
             | 
| 145 | 
            +
             | 
| 146 | 
            +
                        return nil if @attributes.include?(name) && @attributes[name].nil? && method_attrs.empty?
         | 
| 147 | 
            +
             | 
| 148 | 
            +
                        if @attributes[name].blank? || method_attrs.any?
         | 
| 149 | 
            +
                          path = begin
         | 
| 150 | 
            +
                            self.class.build_request_path(@attributes.merge(method_attrs))
         | 
| 151 | 
            +
                          rescue Her::Errors::PathError
         | 
| 152 | 
            +
                            return nil
         | 
| 153 | 
            +
                          end
         | 
| 154 | 
            +
             | 
| 155 | 
            +
                          @attributes[name] = klass.get_resource("#{path}#{attrs[:path]}", method_attrs)
         | 
| 137 156 | 
             
                        end
         | 
| 157 | 
            +
             | 
| 158 | 
            +
                        @attributes[name]
         | 
| 138 159 | 
             
                      end
         | 
| 139 160 | 
             
                    end
         | 
| 140 161 |  | 
| 141 | 
            -
                    # Define a *belongs_to*  | 
| 162 | 
            +
                    # Define a *belongs_to* association.
         | 
| 142 163 | 
             
                    #
         | 
| 143 164 | 
             
                    # @param [Symbol] name The name of the model
         | 
| 144 165 | 
             
                    # @param [Hash] attrs Options (currently not used)
         | 
| @@ -160,29 +181,29 @@ module Her | |
| 160 181 | 
             
                      attrs = {
         | 
| 161 182 | 
             
                        :class_name => name.to_s.classify,
         | 
| 162 183 | 
             
                        :name => name,
         | 
| 184 | 
            +
                        :data_key => name,
         | 
| 163 185 | 
             
                        :foreign_key => "#{name}_id",
         | 
| 164 186 | 
             
                        :path => "/#{name.to_s.pluralize}/:id"
         | 
| 165 187 | 
             
                      }.merge(attrs)
         | 
| 166 | 
            -
                      ( | 
| 188 | 
            +
                      (associations[:belongs_to] ||= []) << attrs
         | 
| 167 189 |  | 
| 168 190 | 
             
                      define_method(name) do |*method_attrs|
         | 
| 169 191 | 
             
                        method_attrs = method_attrs[0] || {}
         | 
| 170 192 | 
             
                        klass = self.class.nearby_class(attrs[:class_name])
         | 
| 171 | 
            -
             | 
| 172 | 
            -
             | 
| 173 | 
            -
             | 
| 174 | 
            -
             | 
| 193 | 
            +
             | 
| 194 | 
            +
                        return nil if @attributes.include?(name) && @attributes[name].nil? && method_attrs.empty?
         | 
| 195 | 
            +
             | 
| 196 | 
            +
                        if @attributes[name].blank? || method_attrs.any?
         | 
| 197 | 
            +
                          path = begin
         | 
| 198 | 
            +
                            klass.build_request_path(@attributes.merge(method_attrs.merge(:id => @attributes[attrs[:foreign_key].to_sym])))
         | 
| 199 | 
            +
                          rescue Her::Errors::PathError
         | 
| 200 | 
            +
                            return nil
         | 
| 201 | 
            +
                          end
         | 
| 202 | 
            +
             | 
| 203 | 
            +
                          @attributes[name] = klass.get_resource("#{path}", method_attrs)
         | 
| 175 204 | 
             
                        end
         | 
| 176 | 
            -
                      end
         | 
| 177 | 
            -
                    end
         | 
| 178 205 |  | 
| 179 | 
            -
             | 
| 180 | 
            -
                    def relationship_accessor(type, attrs)
         | 
| 181 | 
            -
                      name = attrs[:name]
         | 
| 182 | 
            -
                      class_name = attrs[:class_name]
         | 
| 183 | 
            -
                      define_method(name) do
         | 
| 184 | 
            -
                        klass = self.class.nearby_class(attrs[:class_name])
         | 
| 185 | 
            -
                        @data[name] ||= klass.get_resource("#{klass.build_request_path(attrs[:path], :id => @data[attrs[:foreign_key].to_sym])}")
         | 
| 206 | 
            +
                        @attributes[name]
         | 
| 186 207 | 
             
                      end
         | 
| 187 208 | 
             
                    end
         | 
| 188 209 | 
             
                  end
         | 
| @@ -12,7 +12,7 @@ module Her | |
| 12 12 | 
             
                  #   @user = User.find(1)
         | 
| 13 13 | 
             
                  #   p @user # => #<User(/users/1) id=1 name="Tobias Fünke">
         | 
| 14 14 | 
             
                  def inspect
         | 
| 15 | 
            -
                    "#<#{self.class}(#{request_path}) #{ | 
| 15 | 
            +
                    "#<#{self.class}(#{request_path}) #{attributes.keys.map { |k| "#{k}=#{attribute_for_inspect(send(k))}" }.join(" ")}>"
         | 
| 16 16 | 
             
                  end
         | 
| 17 17 |  | 
| 18 18 | 
             
                  private
         | 
| @@ -4,52 +4,52 @@ module Her | |
| 4 4 | 
             
                  extend ActiveSupport::Concern
         | 
| 5 5 |  | 
| 6 6 | 
             
                  module ClassMethods
         | 
| 7 | 
            -
                    def accepts_nested_attributes_for(* | 
| 8 | 
            -
                       | 
| 7 | 
            +
                    def accepts_nested_attributes_for(*association_names)
         | 
| 8 | 
            +
                      association_names.each do |association_name|
         | 
| 9 9 | 
             
                        type = nil
         | 
| 10 | 
            -
                        [:belongs_to, :has_one, :has_many].each do | | 
| 11 | 
            -
                          if ! | 
| 12 | 
            -
                            type =  | 
| 10 | 
            +
                        [:belongs_to, :has_one, :has_many].each do |association_type|
         | 
| 11 | 
            +
                          if !associations[association_type].nil? && associations[association_type].any? { |association| association[:name] == association_name }
         | 
| 12 | 
            +
                            type = association_type
         | 
| 13 13 | 
             
                          end
         | 
| 14 14 | 
             
                        end
         | 
| 15 15 | 
             
                        if type.nil?
         | 
| 16 | 
            -
                          raise( | 
| 16 | 
            +
                          raise(AssociationUnknownError.new("Unknown association name :#{association_name}"))
         | 
| 17 17 | 
             
                        end
         | 
| 18 18 | 
             
                        class_eval <<-eoruby, __FILE__, __LINE__ + 1
         | 
| 19 | 
            -
                          if method_defined?(:#{ | 
| 20 | 
            -
                            remove_method(:#{ | 
| 19 | 
            +
                          if method_defined?(:#{association_name}_attributes=)
         | 
| 20 | 
            +
                            remove_method(:#{association_name}_attributes=)
         | 
| 21 21 | 
             
                          end
         | 
| 22 | 
            -
                          def #{ | 
| 23 | 
            -
                            assign_nested_attributes_for_#{type} | 
| 22 | 
            +
                          def #{association_name}_attributes=(attributes)
         | 
| 23 | 
            +
                            assign_nested_attributes_for_#{type}_association(:#{association_name}, attributes)
         | 
| 24 24 | 
             
                          end
         | 
| 25 25 | 
             
                        eoruby
         | 
| 26 26 | 
             
                      end
         | 
| 27 27 | 
             
                    end
         | 
| 28 28 | 
             
                  end
         | 
| 29 29 |  | 
| 30 | 
            -
                  def  | 
| 31 | 
            -
                     | 
| 30 | 
            +
                  def assign_nested_attributes_for_belongs_to_association(association_name, attributes)
         | 
| 31 | 
            +
                    assign_nested_attributes_for_simple_association(:belongs_to, association_name, attributes)
         | 
| 32 32 | 
             
                  end
         | 
| 33 33 |  | 
| 34 | 
            -
                  def  | 
| 35 | 
            -
                     | 
| 34 | 
            +
                  def assign_nested_attributes_for_has_one_association(association_name, attributes)
         | 
| 35 | 
            +
                    assign_nested_attributes_for_simple_association(:has_one, association_name, attributes)
         | 
| 36 36 | 
             
                  end
         | 
| 37 37 |  | 
| 38 | 
            -
                  def  | 
| 39 | 
            -
                     | 
| 40 | 
            -
                    klass = self.class.nearby_class( | 
| 41 | 
            -
                    self.send("#{ | 
| 38 | 
            +
                  def assign_nested_attributes_for_has_many_association(association_name, attributes)
         | 
| 39 | 
            +
                    association = self.class.associations[:has_many].find { |association| association[:name] == association_name }
         | 
| 40 | 
            +
                    klass = self.class.nearby_class(association[:class_name])
         | 
| 41 | 
            +
                    self.send("#{association[:name]}=", Her::Model::ORM.initialize_collection(klass, :data => attributes))
         | 
| 42 42 | 
             
                  end
         | 
| 43 43 |  | 
| 44 44 | 
             
                  private
         | 
| 45 | 
            -
                  def  | 
| 46 | 
            -
                     | 
| 47 | 
            -
                    if has_data?( | 
| 48 | 
            -
                      self.send("#{ | 
| 45 | 
            +
                  def assign_nested_attributes_for_simple_association(association_type, association_name, attributes)
         | 
| 46 | 
            +
                    association = self.class.associations[association_type].find { |association| association[:name] == association_name }
         | 
| 47 | 
            +
                    if has_data?(association[:name])
         | 
| 48 | 
            +
                      self.send("#{association[:name]}").assign_data(attributes)
         | 
| 49 49 | 
             
                    else
         | 
| 50 | 
            -
                      klass = self.class.nearby_class( | 
| 50 | 
            +
                      klass = self.class.nearby_class(association[:class_name])
         | 
| 51 51 | 
             
                      instance = klass.new(klass.parse(attributes))
         | 
| 52 | 
            -
                      self.send("#{ | 
| 52 | 
            +
                      self.send("#{association[:name]}=", instance)
         | 
| 53 53 | 
             
                    end
         | 
| 54 54 | 
             
                  end
         | 
| 55 55 | 
             
                end
         | 
    
        data/lib/her/model/orm.rb
    CHANGED
    
    | @@ -3,17 +3,18 @@ module Her | |
| 3 3 | 
             
                # This module adds ORM-like capabilities to the model
         | 
| 4 4 | 
             
                module ORM
         | 
| 5 5 | 
             
                  extend ActiveSupport::Concern
         | 
| 6 | 
            -
                  attr_accessor : | 
| 7 | 
            -
                  alias : | 
| 8 | 
            -
                  alias : | 
| 6 | 
            +
                  attr_accessor :attributes, :metadata, :response_errors
         | 
| 7 | 
            +
                  alias :data :attributes
         | 
| 8 | 
            +
                  alias :data= :attributes=
         | 
| 9 9 |  | 
| 10 10 | 
             
                  # Initialize a new object with data received from an HTTP request
         | 
| 11 | 
            -
                  def initialize( | 
| 12 | 
            -
                     | 
| 13 | 
            -
                    @ | 
| 14 | 
            -
                    @ | 
| 11 | 
            +
                  def initialize(attributes={})
         | 
| 12 | 
            +
                    attributes ||= {}
         | 
| 13 | 
            +
                    @metadata = attributes.delete(:_metadata) || {}
         | 
| 14 | 
            +
                    @response_errors = attributes.delete(:_errors) || {}
         | 
| 15 | 
            +
                    @destroyed = attributes.delete(:_destroyed) || false
         | 
| 15 16 |  | 
| 16 | 
            -
                     | 
| 17 | 
            +
                    update_attributes(attributes)
         | 
| 17 18 | 
             
                  end
         | 
| 18 19 |  | 
| 19 20 | 
             
                  # Initialize a collection of resources
         | 
| @@ -32,6 +33,7 @@ module Her | |
| 32 33 | 
             
                  # @private
         | 
| 33 34 | 
             
                  def self.use_setter_methods(model, params)
         | 
| 34 35 | 
             
                    setter_method_names = model.class.setter_method_names
         | 
| 36 | 
            +
                    params ||= {}
         | 
| 35 37 | 
             
                    params.inject({}) do |memo, (key, value)|
         | 
| 36 38 | 
             
                      setter_method = key.to_s + '='
         | 
| 37 39 | 
             
                      if setter_method_names.include?(setter_method)
         | 
| @@ -46,16 +48,18 @@ module Her | |
| 46 48 | 
             
                    end
         | 
| 47 49 | 
             
                  end
         | 
| 48 50 |  | 
| 49 | 
            -
                  # Handles missing methods | 
| 51 | 
            +
                  # Handles missing methods
         | 
| 50 52 | 
             
                  # @private
         | 
| 51 53 | 
             
                  def method_missing(method, *args, &blk)
         | 
| 52 | 
            -
                    if method.to_s. | 
| 53 | 
            -
                       | 
| 54 | 
            -
                       | 
| 55 | 
            -
             | 
| 56 | 
            -
                       | 
| 57 | 
            -
             | 
| 58 | 
            -
             | 
| 54 | 
            +
                    if method.to_s =~ /[?=]$/ || attributes.include?(method)
         | 
| 55 | 
            +
                      # Extract the attribute
         | 
| 56 | 
            +
                      attribute = method.to_s.sub(/[?=]$/, '')
         | 
| 57 | 
            +
             | 
| 58 | 
            +
                      # Create a new `attribute` methods set
         | 
| 59 | 
            +
                      self.class.attributes(*attribute)
         | 
| 60 | 
            +
             | 
| 61 | 
            +
                      # Resend the method!
         | 
| 62 | 
            +
                      send(method, *args, &blk)
         | 
| 59 63 | 
             
                    else
         | 
| 60 64 | 
             
                      super
         | 
| 61 65 | 
             
                    end
         | 
| @@ -63,44 +67,45 @@ module Her | |
| 63 67 |  | 
| 64 68 | 
             
                  # Handles returning true for the cases handled by method_missing
         | 
| 65 69 | 
             
                  def respond_to?(method, include_private = false)
         | 
| 66 | 
            -
                    method.to_s.end_with?('=') || method.to_s.end_with?('?') || @ | 
| 70 | 
            +
                    method.to_s.end_with?('=') || method.to_s.end_with?('?') || @attributes.include?(method) || super
         | 
| 67 71 | 
             
                  end
         | 
| 68 72 |  | 
| 69 73 | 
             
                  def respond_to_missing?(method, include_private = false)
         | 
| 70 | 
            -
                    method.to_s.end_with?('=') || method.to_s.end_with?('?') || @ | 
| 74 | 
            +
                    method.to_s.end_with?('=') || method.to_s.end_with?('?') || @attributes.include?(method) || @attributes.include?(method) || super
         | 
| 71 75 | 
             
                  end
         | 
| 72 76 |  | 
| 73 77 | 
             
                  # Assign new data to an instance
         | 
| 74 | 
            -
                  def  | 
| 75 | 
            -
                     | 
| 76 | 
            -
                     | 
| 78 | 
            +
                  def assign_attributes(new_attributes)
         | 
| 79 | 
            +
                    new_attributes = Her::Model::ORM.use_setter_methods(self, new_attributes)
         | 
| 80 | 
            +
                    attributes.update new_attributes
         | 
| 77 81 | 
             
                  end
         | 
| 78 | 
            -
                  alias : | 
| 82 | 
            +
                  alias :assign_data :assign_attributes
         | 
| 79 83 |  | 
| 80 84 | 
             
                  # Handles returning true for the accessible attributes
         | 
| 81 | 
            -
                  def  | 
| 82 | 
            -
                     | 
| 85 | 
            +
                  def has_attribute?(attribute_name)
         | 
| 86 | 
            +
                    attributes.include?(attribute_name)
         | 
| 83 87 | 
             
                  end
         | 
| 88 | 
            +
                  alias :has_data? :has_attribute?
         | 
| 84 89 |  | 
| 85 | 
            -
                   | 
| 86 | 
            -
             | 
| 87 | 
            -
                    @data[attribute_name]
         | 
| 90 | 
            +
                  def get_attribute(attribute_name)
         | 
| 91 | 
            +
                    attributes[attribute_name]
         | 
| 88 92 | 
             
                  end
         | 
| 93 | 
            +
                  alias :get_data :get_attribute
         | 
| 89 94 |  | 
| 90 95 | 
             
                  # Override the method to prevent from returning the object ID (in ruby-1.8.7)
         | 
| 91 96 | 
             
                  # @private
         | 
| 92 97 | 
             
                  def id
         | 
| 93 | 
            -
                     | 
| 98 | 
            +
                    attributes[:id] || super
         | 
| 94 99 | 
             
                  end
         | 
| 95 100 |  | 
| 96 101 | 
             
                  # Return `true` if a resource was not saved yet
         | 
| 97 102 | 
             
                  def new?
         | 
| 98 | 
            -
                     | 
| 103 | 
            +
                    !attributes.include?(:id)
         | 
| 99 104 | 
             
                  end
         | 
| 100 105 |  | 
| 101 106 | 
             
                  # Return `true` if the other object is also a Her::Model and has matching data
         | 
| 102 107 | 
             
                  def ==(other)
         | 
| 103 | 
            -
                    other.is_a?(Her::Model) &&  | 
| 108 | 
            +
                    other.is_a?(Her::Model) && attributes == other.attributes
         | 
| 104 109 | 
             
                  end
         | 
| 105 110 |  | 
| 106 111 | 
             
                  # Delegate to the == method
         | 
| @@ -108,10 +113,10 @@ module Her | |
| 108 113 | 
             
                    self == other
         | 
| 109 114 | 
             
                  end
         | 
| 110 115 |  | 
| 111 | 
            -
                  # Delegate to @ | 
| 116 | 
            +
                  # Delegate to @attributes, allowing models to act correctly in code like:
         | 
| 112 117 | 
             
                  #     [ Model.find(1), Model.find(1) ].uniq # => [ Model.find(1) ]
         | 
| 113 118 | 
             
                  def hash
         | 
| 114 | 
            -
                     | 
| 119 | 
            +
                    attributes.hash
         | 
| 115 120 | 
             
                  end
         | 
| 116 121 |  | 
| 117 122 | 
             
                  # Return whether the object has been destroyed
         | 
| @@ -136,7 +141,7 @@ module Her | |
| 136 141 | 
             
                    params = to_params
         | 
| 137 142 | 
             
                    resource = self
         | 
| 138 143 |  | 
| 139 | 
            -
                    if  | 
| 144 | 
            +
                    if attributes[:id]
         | 
| 140 145 | 
             
                      callback = :update
         | 
| 141 146 | 
             
                      method = :put
         | 
| 142 147 | 
             
                    else
         | 
| @@ -147,12 +152,12 @@ module Her | |
| 147 152 | 
             
                    run_callbacks callback do
         | 
| 148 153 | 
             
                      run_callbacks :save do
         | 
| 149 154 | 
             
                        self.class.request(params.merge(:_method => method, :_path => "#{request_path}")) do |parsed_data, response|
         | 
| 150 | 
            -
                           | 
| 155 | 
            +
                          update_attributes(self.class.parse(parsed_data[:data])) if parsed_data[:data].any?
         | 
| 151 156 | 
             
                          self.metadata = parsed_data[:metadata]
         | 
| 152 157 | 
             
                          self.response_errors = parsed_data[:errors]
         | 
| 153 158 | 
             
                          self.changed_attributes.clear if self.changed_attributes.present?
         | 
| 154 159 |  | 
| 155 | 
            -
                          return false if self.response_errors.any?
         | 
| 160 | 
            +
                          return false if !response.success? || self.response_errors.any?
         | 
| 156 161 | 
             
                        end
         | 
| 157 162 | 
             
                      end
         | 
| 158 163 | 
             
                    end
         | 
| @@ -170,7 +175,7 @@ module Her | |
| 170 175 | 
             
                    resource = self
         | 
| 171 176 | 
             
                    run_callbacks :destroy do
         | 
| 172 177 | 
             
                      self.class.request(:_method => :delete, :_path => "#{request_path}") do |parsed_data, response|
         | 
| 173 | 
            -
                         | 
| 178 | 
            +
                        update_attributes(self.class.parse(parsed_data[:data])) if parsed_data[:data].any?
         | 
| 174 179 | 
             
                        self.metadata = parsed_data[:metadata]
         | 
| 175 180 | 
             
                        self.response_errors = parsed_data[:errors]
         | 
| 176 181 | 
             
                        @destroyed = true
         | 
| @@ -180,13 +185,13 @@ module Her | |
| 180 185 | 
             
                  end
         | 
| 181 186 |  | 
| 182 187 | 
             
                  # @private
         | 
| 183 | 
            -
                  def  | 
| 184 | 
            -
                    @ | 
| 185 | 
            -
                    # Use setter methods first, then translate attributes of  | 
| 186 | 
            -
                    # into  | 
| 187 | 
            -
                     | 
| 188 | 
            -
                     | 
| 189 | 
            -
                     | 
| 188 | 
            +
                  def update_attributes(raw_data)
         | 
| 189 | 
            +
                    @attributes ||= {}
         | 
| 190 | 
            +
                    # Use setter methods first, then translate attributes of associations
         | 
| 191 | 
            +
                    # into association instances, then merge the parsed_data into @attributes.
         | 
| 192 | 
            +
                    unset_attributes = Her::Model::ORM.use_setter_methods(self, raw_data)
         | 
| 193 | 
            +
                    parsed_attributes = self.class.parse_associations(unset_attributes)
         | 
| 194 | 
            +
                    attributes.update(parsed_attributes)
         | 
| 190 195 | 
             
                  end
         | 
| 191 196 |  | 
| 192 197 | 
             
                  # Convert into a hash of request parameters
         | 
| @@ -196,9 +201,9 @@ module Her | |
| 196 201 | 
             
                  #   # => { :id => 1, :name => 'John Smith' }
         | 
| 197 202 | 
             
                  def to_params
         | 
| 198 203 | 
             
                    if self.class.include_root_in_json
         | 
| 199 | 
            -
                      { (self.class.include_root_in_json == true ? self.class.root_element : self.class.include_root_in_json) =>  | 
| 204 | 
            +
                      { (self.class.include_root_in_json == true ? self.class.root_element : self.class.include_root_in_json) => attributes.dup }
         | 
| 200 205 | 
             
                    else
         | 
| 201 | 
            -
                       | 
| 206 | 
            +
                      attributes.dup
         | 
| 202 207 | 
             
                    end
         | 
| 203 208 | 
             
                  end
         | 
| 204 209 |  | 
| @@ -220,16 +225,16 @@ module Her | |
| 220 225 | 
             
                        attribute = attribute.to_sym
         | 
| 221 226 |  | 
| 222 227 | 
             
                        define_method "#{attribute}".to_sym do
         | 
| 223 | 
            -
                          @ | 
| 228 | 
            +
                          @attributes.include?(attribute) ? @attributes[attribute] : nil
         | 
| 224 229 | 
             
                        end
         | 
| 225 230 |  | 
| 226 231 | 
             
                        define_method "#{attribute}=".to_sym do |value|
         | 
| 227 | 
            -
                          self.send("#{attribute}_will_change!".to_sym) if @ | 
| 228 | 
            -
                          @ | 
| 232 | 
            +
                          self.send("#{attribute}_will_change!".to_sym) if @attributes[attribute] != value
         | 
| 233 | 
            +
                          @attributes[attribute] = value
         | 
| 229 234 | 
             
                        end
         | 
| 230 235 |  | 
| 231 236 | 
             
                        define_method "#{attribute}?".to_sym do
         | 
| 232 | 
            -
                          @ | 
| 237 | 
            +
                          @attributes.include?(attribute) && @attributes[attribute].present?
         | 
| 233 238 | 
             
                        end
         | 
| 234 239 | 
             
                      end
         | 
| 235 240 | 
             
                    end
         | 
| @@ -299,7 +304,7 @@ module Her | |
| 299 304 | 
             
                          request(params.merge(:_method => :post, :_path => "#{build_request_path(params)}")) do |parsed_data, response|
         | 
| 300 305 | 
             
                            data = parse(parsed_data[:data])
         | 
| 301 306 | 
             
                            resource.instance_eval do
         | 
| 302 | 
            -
                               | 
| 307 | 
            +
                              update_attributes(data)
         | 
| 303 308 | 
             
                              @metadata = parsed_data[:metadata]
         | 
| 304 309 | 
             
                              @response_errors = parsed_data[:errors]
         | 
| 305 310 | 
             
                              @changed_attributes.clear if @changed_attributes.present?
         | 
    
        data/lib/her/model/paths.rb
    CHANGED
    
    | @@ -12,7 +12,7 @@ module Her | |
| 12 12 | 
             
                  #
         | 
| 13 13 | 
             
                  #   User.find(1) # Fetched via GET /utilisateurs/1
         | 
| 14 14 | 
             
                  def request_path
         | 
| 15 | 
            -
                    self.class.build_request_path( | 
| 15 | 
            +
                    self.class.build_request_path(attributes.dup)
         | 
| 16 16 | 
             
                  end
         | 
| 17 17 |  | 
| 18 18 | 
             
                  module ClassMethods
         | 
| @@ -67,7 +67,7 @@ module Her | |
| 67 67 |  | 
| 68 68 | 
             
                      path.gsub(/:([\w_]+)/) do
         | 
| 69 69 | 
             
                        # Look for :key or :_key, otherwise raise an exception
         | 
| 70 | 
            -
                        parameters.delete($1.to_sym) || parameters.delete("_#{$1}".to_sym) || raise(Her::Errors::PathError | 
| 70 | 
            +
                        parameters.delete($1.to_sym) || parameters.delete("_#{$1}".to_sym) || raise(Her::Errors::PathError, "Missing :_#{$1} parameter to build the request path. Path is `#{path}`. Parameters are `#{parameters.inspect}`.")
         | 
| 71 71 | 
             
                      end
         | 
| 72 72 | 
             
                    end
         | 
| 73 73 |  | 
    
        data/lib/her/version.rb
    CHANGED
    
    
| @@ -1,100 +1,100 @@ | |
| 1 1 | 
             
            # encoding: utf-8
         | 
| 2 2 | 
             
            require File.join(File.dirname(__FILE__), "../spec_helper.rb")
         | 
| 3 3 |  | 
| 4 | 
            -
            describe Her::Model:: | 
| 5 | 
            -
              context "setting  | 
| 4 | 
            +
            describe Her::Model::Associations do
         | 
| 5 | 
            +
              context "setting associations without details" do
         | 
| 6 6 | 
             
                before do
         | 
| 7 7 | 
             
                  spawn_model "Foo::User"
         | 
| 8 8 | 
             
                end
         | 
| 9 9 |  | 
| 10 | 
            -
                it "handles a single 'has_many'  | 
| 10 | 
            +
                it "handles a single 'has_many' association" do
         | 
| 11 11 | 
             
                  Foo::User.has_many :comments
         | 
| 12 | 
            -
                  Foo::User. | 
| 12 | 
            +
                  Foo::User.associations[:has_many].should == [{ :name => :comments, :data_key => :comments, :class_name => "Comment", :path => "/comments", :inverse_of => nil }]
         | 
| 13 13 | 
             
                end
         | 
| 14 14 |  | 
| 15 | 
            -
                it "handles multiples 'has_many'  | 
| 15 | 
            +
                it "handles multiples 'has_many' association" do
         | 
| 16 16 | 
             
                  Foo::User.has_many :comments
         | 
| 17 17 | 
             
                  Foo::User.has_many :posts
         | 
| 18 | 
            -
                  Foo::User. | 
| 18 | 
            +
                  Foo::User.associations[:has_many].should == [{ :name => :comments, :data_key => :comments, :class_name => "Comment", :path => "/comments", :inverse_of => nil }, { :name => :posts, :data_key => :posts, :class_name => "Post", :path => "/posts", :inverse_of => nil }]
         | 
| 19 19 | 
             
                end
         | 
| 20 20 |  | 
| 21 | 
            -
                it "handles a single 'has_one'  | 
| 21 | 
            +
                it "handles a single 'has_one' association" do
         | 
| 22 22 | 
             
                  Foo::User.has_one :category
         | 
| 23 | 
            -
                  Foo::User. | 
| 23 | 
            +
                  Foo::User.associations[:has_one].should == [{ :name => :category, :data_key => :category, :class_name => "Category", :path => "/category" }]
         | 
| 24 24 | 
             
                end
         | 
| 25 25 |  | 
| 26 | 
            -
                it "handles multiples 'has_one'  | 
| 26 | 
            +
                it "handles multiples 'has_one' association" do
         | 
| 27 27 | 
             
                  Foo::User.has_one :category
         | 
| 28 28 | 
             
                  Foo::User.has_one :role
         | 
| 29 | 
            -
                  Foo::User. | 
| 29 | 
            +
                  Foo::User.associations[:has_one].should == [{ :name => :category, :data_key => :category, :class_name => "Category", :path => "/category" }, { :name => :role, :data_key => :role, :class_name => "Role", :path => "/role" }]
         | 
| 30 30 | 
             
                end
         | 
| 31 31 |  | 
| 32 | 
            -
                it "handles a single belongs_to  | 
| 32 | 
            +
                it "handles a single belongs_to association" do
         | 
| 33 33 | 
             
                  Foo::User.belongs_to :organization
         | 
| 34 | 
            -
                  Foo::User. | 
| 34 | 
            +
                  Foo::User.associations[:belongs_to].should == [{ :name => :organization, :data_key => :organization, :class_name => "Organization", :foreign_key => "organization_id", :path => "/organizations/:id" }]
         | 
| 35 35 | 
             
                end
         | 
| 36 36 |  | 
| 37 | 
            -
                it "handles multiples 'belongs_to'  | 
| 37 | 
            +
                it "handles multiples 'belongs_to' association" do
         | 
| 38 38 | 
             
                  Foo::User.belongs_to :organization
         | 
| 39 39 | 
             
                  Foo::User.belongs_to :family
         | 
| 40 | 
            -
                  Foo::User. | 
| 40 | 
            +
                  Foo::User.associations[:belongs_to].should == [{ :name => :organization, :data_key => :organization, :class_name => "Organization", :foreign_key => "organization_id", :path => "/organizations/:id" }, { :name => :family, :data_key => :family, :class_name => "Family", :foreign_key => "family_id", :path => "/families/:id" }]
         | 
| 41 41 | 
             
                end
         | 
| 42 42 | 
             
              end
         | 
| 43 43 |  | 
| 44 | 
            -
              context "setting  | 
| 44 | 
            +
              context "setting associations with details" do
         | 
| 45 45 | 
             
                before do
         | 
| 46 46 | 
             
                  spawn_model "Foo::User"
         | 
| 47 47 | 
             
                end
         | 
| 48 48 |  | 
| 49 | 
            -
                it "handles a single 'has_many'  | 
| 50 | 
            -
                  Foo::User.has_many :comments, :class_name => "Post", :inverse_of => :admin
         | 
| 51 | 
            -
                  Foo::User. | 
| 49 | 
            +
                it "handles a single 'has_many' association" do
         | 
| 50 | 
            +
                  Foo::User.has_many :comments, :class_name => "Post", :inverse_of => :admin, :data_key => :user_comments
         | 
| 51 | 
            +
                  Foo::User.associations[:has_many].should == [{ :name => :comments, :data_key => :user_comments, :class_name => "Post", :path => "/comments", :inverse_of => :admin }]
         | 
| 52 52 | 
             
                end
         | 
| 53 53 |  | 
| 54 | 
            -
                it "handles a single 'has_one'  | 
| 55 | 
            -
                  Foo::User.has_one :category, :class_name => "Topic", :foreign_key => "topic_id"
         | 
| 56 | 
            -
                  Foo::User. | 
| 54 | 
            +
                it "handles a single 'has_one' association" do
         | 
| 55 | 
            +
                  Foo::User.has_one :category, :class_name => "Topic", :foreign_key => "topic_id", :data_key => :topic
         | 
| 56 | 
            +
                  Foo::User.associations[:has_one].should == [{ :name => :category, :data_key => :topic, :class_name => "Topic", :foreign_key => "topic_id", :path => "/category" }]
         | 
| 57 57 | 
             
                end
         | 
| 58 58 |  | 
| 59 | 
            -
                it "handles a single belongs_to  | 
| 60 | 
            -
                  Foo::User.belongs_to :organization, :class_name => "Business", :foreign_key => "org_id"
         | 
| 61 | 
            -
                  Foo::User. | 
| 59 | 
            +
                it "handles a single belongs_to association" do
         | 
| 60 | 
            +
                  Foo::User.belongs_to :organization, :class_name => "Business", :foreign_key => "org_id", :data_key => :org
         | 
| 61 | 
            +
                  Foo::User.associations[:belongs_to].should == [{ :name => :organization, :data_key => :org, :class_name => "Business", :foreign_key => "org_id", :path => "/organizations/:id" }]
         | 
| 62 62 | 
             
                end
         | 
| 63 63 |  | 
| 64 | 
            -
                context "inheriting  | 
| 65 | 
            -
                  it "copies  | 
| 64 | 
            +
                context "inheriting associations from a superclass" do
         | 
| 65 | 
            +
                  it "copies associations to the subclass" do
         | 
| 66 66 | 
             
                    Foo::User.has_many :comments, :class_name => "Post"
         | 
| 67 67 | 
             
                    subclass = Class.new(Foo::User)
         | 
| 68 | 
            -
                    subclass. | 
| 69 | 
            -
                    subclass. | 
| 70 | 
            -
                    subclass. | 
| 68 | 
            +
                    subclass.associations.object_id.should_not == Foo::User.associations.object_id
         | 
| 69 | 
            +
                    subclass.associations[:has_many].length.should == 1
         | 
| 70 | 
            +
                    subclass.associations[:has_many].first[:class_name].should == "Post"
         | 
| 71 71 | 
             
                  end
         | 
| 72 72 | 
             
                end
         | 
| 73 73 | 
             
              end
         | 
| 74 74 |  | 
| 75 | 
            -
              context "handling  | 
| 75 | 
            +
              context "handling associations without details" do
         | 
| 76 76 | 
             
                before do
         | 
| 77 77 | 
             
                  Her::API.setup :url => "https://api.example.com" do |builder|
         | 
| 78 78 | 
             
                    builder.use Her::Middleware::FirstLevelParseJSON
         | 
| 79 79 | 
             
                    builder.use Faraday::Request::UrlEncoded
         | 
| 80 80 | 
             
                    builder.adapter :test do |stub|
         | 
| 81 | 
            -
                      stub.get("/users/1") { |env| [200, {}, { :id => 1, :name => "Tobias Fünke", :comments => [{ :id => 2, :body => "Tobias, you blow hard!", :user_id => 1 }, { :id => 3, :body => "I wouldn't mind kissing that man between the cheeks, so to speak", :user_id => 1 }], :role => { :id => 1, :body => "Admin" }, :organization => { :id => 1, :name => "Bluth Company" }, :organization_id => 1 }.to_json] }
         | 
| 81 | 
            +
                      stub.get("/users/1") { |env| [200, {}, { :id => 1, :name => "Tobias Fünke", :comments => [{ :comment => { :id => 2, :body => "Tobias, you blow hard!", :user_id => 1 } }, { :comment => { :id => 3, :body => "I wouldn't mind kissing that man between the cheeks, so to speak", :user_id => 1 } }], :role => { :id => 1, :body => "Admin" }, :organization => { :id => 1, :name => "Bluth Company" }, :organization_id => 1 }.to_json] }
         | 
| 82 82 | 
             
                      stub.get("/users/2") { |env| [200, {}, { :id => 2, :name => "Lindsay Fünke", :organization_id => 2 }.to_json] }
         | 
| 83 | 
            -
                      stub.get("/users/1/comments") { |env| [200, {}, [{ :id => 4, :body => "They're having a FIRESALE?" }].to_json] }
         | 
| 84 | 
            -
                      stub.get("/users/2/comments") { |env| [200, {}, [{ :id => 4, :body => "They're having a FIRESALE?" }, { :id => 5, :body => "Is this the tiny town from Footloose?" }].to_json] }
         | 
| 83 | 
            +
                      stub.get("/users/1/comments") { |env| [200, {}, [{ :comment => { :id => 4, :body => "They're having a FIRESALE?" } }].to_json] }
         | 
| 84 | 
            +
                      stub.get("/users/2/comments") { |env| [200, {}, [{ :comment => { :id => 4, :body => "They're having a FIRESALE?" } }, { :comment => { :id => 5, :body => "Is this the tiny town from Footloose?" } }].to_json] }
         | 
| 85 85 | 
             
                      stub.get("/users/2/role") { |env| [200, {}, { :id => 2, :body => "User" }.to_json] }
         | 
| 86 86 | 
             
                      stub.get("/users/1/role") { |env| [200, {}, { :id => 3, :body => "User" }.to_json] }
         | 
| 87 87 | 
             
                      stub.get("/users/1/posts") { |env| [200, {}, {:id => 1, :body => 'blogging stuff', :admin_id => 1 }.to_json] }
         | 
| 88 | 
            -
                      stub.get("/organizations/1") { |env| [200, {}, { :id => 1, :name => "Bluth Company Foo" }.to_json] }
         | 
| 89 | 
            -
                      stub.post("/users") { |env| [200, {}, { :id => 5, :name => "Mr. Krabs", :comments => [{ :id => 99, :body => "Rodríguez, nasibisibusi?", :user_id => 5 }], :role => { :id => 1, :body => "Admin" }, :organization => { :id => 3, :name => "Krusty Krab" }, :organization_id => 3 }.to_json] }
         | 
| 90 | 
            -
                      stub.put("/users/5") { |env| [200, {}, { :id => 5, :name => "Clancy Brown", :comments => [{ :id => 99, :body => "Rodríguez, nasibisibusi?", :user_id => 5 }], :role => { :id => 1, :body => "Admin" }, :organization => { :id => 3, :name => "Krusty Krab" }, :organization_id => 3 }.to_json] }
         | 
| 91 | 
            -
                      stub.delete("/users/5") { |env| [200, {}, { :id => 5, :name => "Clancy Brown", :comments => [{ :id => 99, :body => "Rodríguez, nasibisibusi?", :user_id => 5 }], :role => { :id => 1, :body => "Admin" }, :organization => { :id => 3, :name => "Krusty Krab" }, :organization_id => 3 }.to_json] }
         | 
| 88 | 
            +
                      stub.get("/organizations/1") { |env| [200, {}, { :organization =>  { :id => 1, :name => "Bluth Company Foo" } }.to_json] }
         | 
| 89 | 
            +
                      stub.post("/users") { |env| [200, {}, { :id => 5, :name => "Mr. Krabs", :comments => [{ :comment => { :id => 99, :body => "Rodríguez, nasibisibusi?", :user_id => 5 } }], :role => { :id => 1, :body => "Admin" }, :organization => { :id => 3, :name => "Krusty Krab" }, :organization_id => 3 }.to_json] }
         | 
| 90 | 
            +
                      stub.put("/users/5") { |env| [200, {}, { :id => 5, :name => "Clancy Brown", :comments => [{ :comment => { :id => 99, :body => "Rodríguez, nasibisibusi?", :user_id => 5 } }], :role => { :id => 1, :body => "Admin" }, :organization => { :id => 3, :name => "Krusty Krab" }, :organization_id => 3 }.to_json] }
         | 
| 91 | 
            +
                      stub.delete("/users/5") { |env| [200, {}, { :id => 5, :name => "Clancy Brown", :comments => [{ :comment => { :id => 99, :body => "Rodríguez, nasibisibusi?", :user_id => 5 } }], :role => { :id => 1, :body => "Admin" }, :organization => { :id => 3, :name => "Krusty Krab" }, :organization_id => 3 }.to_json] }
         | 
| 92 92 |  | 
| 93 93 | 
             
                      stub.get("/organizations/2") do |env|
         | 
| 94 94 | 
             
                        if env[:params]["admin"] == "true"
         | 
| 95 | 
            -
                          [200, {}, { :id => 2, :name => "Bluth Company (admin)" }.to_json]
         | 
| 95 | 
            +
                          [200, {}, { :organization => { :id => 2, :name => "Bluth Company (admin)" } }.to_json]
         | 
| 96 96 | 
             
                        else
         | 
| 97 | 
            -
                          [200, {}, { :id => 2, :name => "Bluth Company" }.to_json]
         | 
| 97 | 
            +
                          [200, {}, { :organization => { :id => 2, :name => "Bluth Company" } }.to_json]
         | 
| 98 98 | 
             
                        end
         | 
| 99 99 | 
             
                      end
         | 
| 100 100 | 
             
                    end
         | 
| @@ -108,12 +108,16 @@ describe Her::Model::Relationships do | |
| 108 108 | 
             
                  end
         | 
| 109 109 | 
             
                  spawn_model "Foo::Comment" do
         | 
| 110 110 | 
             
                    belongs_to :user
         | 
| 111 | 
            +
                    parse_root_in_json true
         | 
| 111 112 | 
             
                  end
         | 
| 112 113 | 
             
                  spawn_model "Foo::Post" do
         | 
| 113 114 | 
             
                    belongs_to :admin, :class_name => 'Foo::User'
         | 
| 114 115 | 
             
                  end
         | 
| 115 116 |  | 
| 116 | 
            -
                  spawn_model "Foo::Organization"
         | 
| 117 | 
            +
                  spawn_model "Foo::Organization" do
         | 
| 118 | 
            +
                    parse_root_in_json true
         | 
| 119 | 
            +
                  end
         | 
| 120 | 
            +
             | 
| 117 121 | 
             
                  spawn_model "Foo::Role"
         | 
| 118 122 |  | 
| 119 123 | 
             
                  @user_with_included_data = Foo::User.find(1)
         | 
| @@ -182,14 +186,14 @@ describe Her::Model::Relationships do | |
| 182 186 | 
             
                  @user_with_included_data.organization(:foo_id => 1).name.should == "Bluth Company Foo"
         | 
| 183 187 | 
             
                end
         | 
| 184 188 |  | 
| 185 | 
            -
                it "can tell if it has a  | 
| 186 | 
            -
                  @user_without_included_data. | 
| 187 | 
            -
                  @user_without_included_data. | 
| 189 | 
            +
                it "can tell if it has a association" do
         | 
| 190 | 
            +
                  @user_without_included_data.has_association?(:unknown_association).should be_false
         | 
| 191 | 
            +
                  @user_without_included_data.has_association?(:organization).should be_true
         | 
| 188 192 | 
             
                end
         | 
| 189 193 |  | 
| 190 | 
            -
                it "fetches the resource corresponding to a named  | 
| 191 | 
            -
                  @user_without_included_data. | 
| 192 | 
            -
                  @user_without_included_data. | 
| 194 | 
            +
                it "fetches the resource corresponding to a named association" do
         | 
| 195 | 
            +
                  @user_without_included_data.get_association(:unknown_association).should be_nil
         | 
| 196 | 
            +
                  @user_without_included_data.get_association(:organization).name.should == "Bluth Company"
         | 
| 193 197 | 
             
                end
         | 
| 194 198 |  | 
| 195 199 | 
             
                it "pass query string parameters when additional arguments are passed" do
         | 
| @@ -216,21 +220,21 @@ describe Her::Model::Relationships do | |
| 216 220 | 
             
                end
         | 
| 217 221 | 
             
              end
         | 
| 218 222 |  | 
| 219 | 
            -
              context "handling  | 
| 223 | 
            +
              context "handling associations with details" do
         | 
| 220 224 | 
             
                before do
         | 
| 221 225 | 
             
                  Her::API.setup :url => "https://api.example.com" do |builder|
         | 
| 222 226 | 
             
                    builder.use Her::Middleware::FirstLevelParseJSON
         | 
| 223 227 | 
             
                    builder.use Faraday::Request::UrlEncoded
         | 
| 224 228 | 
             
                    builder.adapter :test do |stub|
         | 
| 225 | 
            -
                      stub.get("/users/1") { |env| [200, {}, { :id => 1, :name => "Tobias Fünke", :organization => { :id => 1, :name => "Bluth Company" }, :organization_id => 1 }.to_json] }
         | 
| 229 | 
            +
                      stub.get("/users/1") { |env| [200, {}, { :id => 1, :name => "Tobias Fünke", :organization => { :id => 1, :name => "Bluth Company Inc." }, :organization_id => 1 }.to_json] }
         | 
| 226 230 | 
             
                      stub.get("/users/2") { |env| [200, {}, { :id => 2, :name => "Lindsay Fünke", :organization_id => 1 }.to_json] }
         | 
| 227 | 
            -
                      stub.get("/users/3") { |env| [200, {}, { :id => 2, :name => "Lindsay Fünke", : | 
| 231 | 
            +
                      stub.get("/users/3") { |env| [200, {}, { :id => 2, :name => "Lindsay Fünke", :company => nil }.to_json] }
         | 
| 228 232 | 
             
                      stub.get("/companies/1") { |env| [200, {}, { :id => 1, :name => "Bluth Company" }.to_json] }
         | 
| 229 233 | 
             
                    end
         | 
| 230 234 | 
             
                  end
         | 
| 231 235 |  | 
| 232 236 | 
             
                  spawn_model "Foo::User" do
         | 
| 233 | 
            -
                    belongs_to :company, :path => "/organizations/:id", :foreign_key => :organization_id
         | 
| 237 | 
            +
                    belongs_to :company, :path => "/organizations/:id", :foreign_key => :organization_id, :data_key => :organization
         | 
| 234 238 | 
             
                  end
         | 
| 235 239 |  | 
| 236 240 | 
             
                  spawn_model "Foo::Company"
         | 
| @@ -243,11 +247,11 @@ describe Her::Model::Relationships do | |
| 243 247 | 
             
                it "maps an array of included data through belongs_to" do
         | 
| 244 248 | 
             
                  @user_with_included_data.company.should be_a(Foo::Company)
         | 
| 245 249 | 
             
                  @user_with_included_data.company.id.should == 1
         | 
| 246 | 
            -
                  @user_with_included_data.company.name.should == "Bluth Company"
         | 
| 250 | 
            +
                  @user_with_included_data.company.name.should == "Bluth Company Inc."
         | 
| 247 251 | 
             
                end
         | 
| 248 252 |  | 
| 249 253 | 
             
                it "does not map included data if it’s nil" do
         | 
| 250 | 
            -
                  @user_with_included_nil_data. | 
| 254 | 
            +
                  @user_with_included_nil_data.company.should be_nil
         | 
| 251 255 | 
             
                end
         | 
| 252 256 |  | 
| 253 257 | 
             
                it "fetches data that was not included through belongs_to" do
         | 
| @@ -2,7 +2,7 @@ | |
| 2 2 | 
             
            require File.join(File.dirname(__FILE__), "../spec_helper.rb")
         | 
| 3 3 |  | 
| 4 4 | 
             
            describe Her::Model::NestedAttributes do
         | 
| 5 | 
            -
              context "with a belongs_to  | 
| 5 | 
            +
              context "with a belongs_to association" do
         | 
| 6 6 | 
             
                before do
         | 
| 7 7 | 
             
                  Her::API.setup :url => "https://api.example.com" do |builder|
         | 
| 8 8 | 
             
                    builder.use Her::Middleware::FirstLevelParseJSON
         | 
| @@ -35,7 +35,7 @@ describe Her::Model::NestedAttributes do | |
| 35 35 | 
             
                end
         | 
| 36 36 | 
             
              end
         | 
| 37 37 |  | 
| 38 | 
            -
              context "with a has_one  | 
| 38 | 
            +
              context "with a has_one association" do
         | 
| 39 39 | 
             
                before do
         | 
| 40 40 | 
             
                  Her::API.setup :url => "https://api.example.com" do |builder|
         | 
| 41 41 | 
             
                    builder.use Her::Middleware::FirstLevelParseJSON
         | 
| @@ -68,7 +68,7 @@ describe Her::Model::NestedAttributes do | |
| 68 68 | 
             
                end
         | 
| 69 69 | 
             
              end
         | 
| 70 70 |  | 
| 71 | 
            -
              context "with a has_many  | 
| 71 | 
            +
              context "with a has_many association" do
         | 
| 72 72 | 
             
                before do
         | 
| 73 73 | 
             
                  Her::API.setup :url => "https://api.example.com" do |builder|
         | 
| 74 74 | 
             
                    builder.use Her::Middleware::FirstLevelParseJSON
         | 
    
        data/spec/model/orm_spec.rb
    CHANGED
    
    | @@ -145,7 +145,7 @@ describe Her::Model::ORM do | |
| 145 145 | 
             
                    builder.use Faraday::Request::UrlEncoded
         | 
| 146 146 | 
             
                    builder.adapter :test do |stub|
         | 
| 147 147 | 
             
                      stub.get("/users/1") { |env| [200, {}, { :id => 1, :friends => ["Maeby", "GOB", "Anne"] }.to_json] }
         | 
| 148 | 
            -
                      stub.get("/users/2") { |env| [200, {}, { :id => 1 | 
| 148 | 
            +
                      stub.get("/users/2") { |env| [200, {}, { :id => 1 }.to_json] }
         | 
| 149 149 | 
             
                    end
         | 
| 150 150 | 
             
                  end
         | 
| 151 151 |  | 
| @@ -155,16 +155,11 @@ describe Her::Model::ORM do | |
| 155 155 |  | 
| 156 156 | 
             
                    def friends=(val)
         | 
| 157 157 | 
             
                      val = val.gsub("\r", "").split("\n").map { |friend| friend.gsub(/^\s*\*\s*/, "") } if val and val.is_a?(String)
         | 
| 158 | 
            -
                      @ | 
| 158 | 
            +
                      @attributes[:friends] = val
         | 
| 159 159 | 
             
                    end
         | 
| 160 160 |  | 
| 161 161 | 
             
                    def friends
         | 
| 162 | 
            -
                      @ | 
| 163 | 
            -
                    end
         | 
| 164 | 
            -
             | 
| 165 | 
            -
                    # Why would anybody want to do this? I don’t know.
         | 
| 166 | 
            -
                    def organization=(organization)
         | 
| 167 | 
            -
                      @data[:organization] = { :foo => :bar }
         | 
| 162 | 
            +
                      @attributes[:friends].map { |friend| "* #{friend}" }.join("\n")
         | 
| 168 163 | 
             
                    end
         | 
| 169 164 | 
             
                  end
         | 
| 170 165 | 
             
                end
         | 
| @@ -173,21 +168,16 @@ describe Her::Model::ORM do | |
| 173 168 | 
             
                  @user = User.find(1)
         | 
| 174 169 | 
             
                  @user.friends.should == "* Maeby\n* GOB\n* Anne"
         | 
| 175 170 | 
             
                  @user.instance_eval do
         | 
| 176 | 
            -
                    @ | 
| 171 | 
            +
                    @attributes[:friends] = ["Maeby", "GOB", "Anne"]
         | 
| 177 172 | 
             
                  end
         | 
| 178 173 | 
             
                end
         | 
| 179 174 |  | 
| 180 | 
            -
                it "handles custom setters with relationships" do
         | 
| 181 | 
            -
                  @user = User.find(2)
         | 
| 182 | 
            -
                  @user.organization.should == { :foo => :bar }
         | 
| 183 | 
            -
                end
         | 
| 184 | 
            -
             | 
| 185 175 | 
             
                it "handles custom getters" do
         | 
| 186 176 | 
             
                  @user = User.new
         | 
| 187 177 | 
             
                  @user.friends = "* George\n* Oscar\n* Lucille"
         | 
| 188 178 | 
             
                  @user.friends.should == "* George\n* Oscar\n* Lucille"
         | 
| 189 179 | 
             
                  @user.instance_eval do
         | 
| 190 | 
            -
                    @ | 
| 180 | 
            +
                    @attributes[:friends] = ["George", "Oscar", "Lucille"]
         | 
| 191 181 | 
             
                  end
         | 
| 192 182 | 
             
                end
         | 
| 193 183 | 
             
              end
         | 
    
        data/spec/model/paths_spec.rb
    CHANGED
    
    | @@ -61,7 +61,7 @@ describe Her::Model::Paths do | |
| 61 61 |  | 
| 62 62 | 
             
                    it "raises exceptions when building a path without required custom variables" do
         | 
| 63 63 | 
             
                      Foo::User.collection_path "/organizations/:organization_id/utilisateurs"
         | 
| 64 | 
            -
                      expect { Foo::User.build_request_path(:id => "foo") }.to raise_error(Her::Errors::PathError)
         | 
| 64 | 
            +
                      expect { Foo::User.build_request_path(:id => "foo") }.to raise_error(Her::Errors::PathError, "Missing :_organization_id parameter to build the request path. Path is `/organizations/:organization_id/utilisateurs/:id`. Parameters are `{:id=>\"foo\"}`.")
         | 
| 65 65 | 
             
                    end
         | 
| 66 66 | 
             
                  end
         | 
| 67 67 | 
             
                end
         | 
| @@ -115,12 +115,12 @@ describe Her::Model::Paths do | |
| 115 115 |  | 
| 116 116 | 
             
                    it "raises exceptions when building a path without required custom variables" do
         | 
| 117 117 | 
             
                      Foo::AdminUser.collection_path "/organizations/:organization_id/users"
         | 
| 118 | 
            -
                      expect { Foo::AdminUser.build_request_path(:id => "foo") }.to raise_error(Her::Errors::PathError)
         | 
| 118 | 
            +
                      expect { Foo::AdminUser.build_request_path(:id => "foo") }.to raise_error(Her::Errors::PathError, "Missing :_organization_id parameter to build the request path. Path is `/organizations/:organization_id/users/:id`. Parameters are `{:id=>\"foo\"}`.")
         | 
| 119 119 | 
             
                    end
         | 
| 120 120 |  | 
| 121 121 | 
             
                    it "raises exceptions when building a relative path without required custom variables" do
         | 
| 122 122 | 
             
                      Foo::AdminUser.collection_path "organizations/:organization_id/users"
         | 
| 123 | 
            -
                      expect { Foo::AdminUser.build_request_path(:id => "foo") }.to raise_error(Her::Errors::PathError)
         | 
| 123 | 
            +
                      expect { Foo::AdminUser.build_request_path(:id => "foo") }.to raise_error(Her::Errors::PathError, "Missing :_organization_id parameter to build the request path. Path is `organizations/:organization_id/users/:id`. Parameters are `{:id=>\"foo\"}`.")
         | 
| 124 124 | 
             
                    end
         | 
| 125 125 | 
             
                  end
         | 
| 126 126 | 
             
                end
         | 
    
        metadata
    CHANGED
    
    | @@ -1,14 +1,14 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification
         | 
| 2 2 | 
             
            name: her
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            -
              version: 0.5. | 
| 4 | 
            +
              version: 0.5.2
         | 
| 5 5 | 
             
            platform: ruby
         | 
| 6 6 | 
             
            authors:
         | 
| 7 7 | 
             
            - Rémi Prévost
         | 
| 8 8 | 
             
            autorequire: 
         | 
| 9 9 | 
             
            bindir: bin
         | 
| 10 10 | 
             
            cert_chain: []
         | 
| 11 | 
            -
            date: 2013-03- | 
| 11 | 
            +
            date: 2013-03-30 00:00:00.000000000 Z
         | 
| 12 12 | 
             
            dependencies:
         | 
| 13 13 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 14 14 | 
             
              name: rake
         | 
| @@ -142,19 +142,20 @@ files: | |
| 142 142 | 
             
            - lib/her/middleware/first_level_parse_json.rb
         | 
| 143 143 | 
             
            - lib/her/middleware/second_level_parse_json.rb
         | 
| 144 144 | 
             
            - lib/her/model.rb
         | 
| 145 | 
            +
            - lib/her/model/associations.rb
         | 
| 145 146 | 
             
            - lib/her/model/base.rb
         | 
| 146 147 | 
             
            - lib/her/model/http.rb
         | 
| 147 148 | 
             
            - lib/her/model/introspection.rb
         | 
| 148 149 | 
             
            - lib/her/model/nested_attributes.rb
         | 
| 149 150 | 
             
            - lib/her/model/orm.rb
         | 
| 150 151 | 
             
            - lib/her/model/paths.rb
         | 
| 151 | 
            -
            - lib/her/model/relationships.rb
         | 
| 152 152 | 
             
            - lib/her/version.rb
         | 
| 153 153 | 
             
            - spec/api_spec.rb
         | 
| 154 154 | 
             
            - spec/collection_spec.rb
         | 
| 155 155 | 
             
            - spec/middleware/accept_json_spec.rb
         | 
| 156 156 | 
             
            - spec/middleware/first_level_parse_json_spec.rb
         | 
| 157 157 | 
             
            - spec/middleware/second_level_parse_json_spec.rb
         | 
| 158 | 
            +
            - spec/model/associations_spec.rb
         | 
| 158 159 | 
             
            - spec/model/callbacks_spec.rb
         | 
| 159 160 | 
             
            - spec/model/dirty_spec.rb
         | 
| 160 161 | 
             
            - spec/model/http_spec.rb
         | 
| @@ -162,7 +163,6 @@ files: | |
| 162 163 | 
             
            - spec/model/nested_attributes_spec.rb
         | 
| 163 164 | 
             
            - spec/model/orm_spec.rb
         | 
| 164 165 | 
             
            - spec/model/paths_spec.rb
         | 
| 165 | 
            -
            - spec/model/relationships_spec.rb
         | 
| 166 166 | 
             
            - spec/model/validations_spec.rb
         | 
| 167 167 | 
             
            - spec/model_spec.rb
         | 
| 168 168 | 
             
            - spec/spec_helper.rb
         | 
| @@ -197,6 +197,7 @@ test_files: | |
| 197 197 | 
             
            - spec/middleware/accept_json_spec.rb
         | 
| 198 198 | 
             
            - spec/middleware/first_level_parse_json_spec.rb
         | 
| 199 199 | 
             
            - spec/middleware/second_level_parse_json_spec.rb
         | 
| 200 | 
            +
            - spec/model/associations_spec.rb
         | 
| 200 201 | 
             
            - spec/model/callbacks_spec.rb
         | 
| 201 202 | 
             
            - spec/model/dirty_spec.rb
         | 
| 202 203 | 
             
            - spec/model/http_spec.rb
         | 
| @@ -204,7 +205,6 @@ test_files: | |
| 204 205 | 
             
            - spec/model/nested_attributes_spec.rb
         | 
| 205 206 | 
             
            - spec/model/orm_spec.rb
         | 
| 206 207 | 
             
            - spec/model/paths_spec.rb
         | 
| 207 | 
            -
            - spec/model/relationships_spec.rb
         | 
| 208 208 | 
             
            - spec/model/validations_spec.rb
         | 
| 209 209 | 
             
            - spec/model_spec.rb
         | 
| 210 210 | 
             
            - spec/spec_helper.rb
         |