{"_id":"angularjs-rails-resource","_rev":"7-91820379e3da3d8bf11c1fe4530378a0","name":"angularjs-rails-resource","description":"A resource factory inspired by $resource from AngularJS","dist-tags":{"latest":"2.3.1"},"versions":{"2.1.0":{"name":"angularjs-rails-resource","description":"A resource factory inspired by $resource from AngularJS","version":"2.1.0","main":"angularjs-rails-resource.min.js","homepage":"https://github.com/FineLinePrototyping/angularjs-rails-resource.git","author":"","repository":{"type":"git","url":"git+https://github.com/FineLinePrototyping/angularjs-rails-resource.git"},"keywords":["angular","resources"],"dependencies":{"angular":"~1.0"},"devDependencies":{"grunt":"~0.4.1","grunt-contrib-jshint":"~0.6.0","grunt-contrib-uglify":"~0.2.2","grunt-contrib-concat":"~0.3.0","grunt-contrib-copy":"~0.4.1","grunt-contrib-clean":"~0.5.0","grunt-contrib-watch":"~0.5.1","grunt-contrib-compress":"~0.5.2","grunt-bump":"~0.0.13","karma":"~0.10","karma-jasmine":"~0.1","karma-chrome-launcher":"~0.1","karma-phantomjs-launcher":"~0.1","karma-junit-reporter":"~0.1","q":"~0.9.2","q-io":"~1.10.6","qq":"~0.3.5"},"scripts":{"test":"karma start --single-run --browsers PhantomJS"},"licenses":[{"type":"MIT","url":"https://github.com/FineLinePrototyping/angularjs-rails-resource.js/blob/master/LICENSE"}],"gitHead":"7fcb2d28f5267549d7e1b1d6efd6a565296a2e27","bugs":{"url":"https://github.com/FineLinePrototyping/angularjs-rails-resource/issues"},"_id":"angularjs-rails-resource@2.1.0","_shasum":"81416284475008f1163d330a52b0489b9211c2a0","_from":".","_npmVersion":"2.11.3","_nodeVersion":"0.12.7","_npmUser":{"name":"tpodom","email":"tommy.odom@gmail.com"},"maintainers":[{"name":"tpodom","email":"tommy.odom@gmail.com"}],"dist":{"shasum":"81416284475008f1163d330a52b0489b9211c2a0","tarball":"https://registry.npmjs.org/angularjs-rails-resource/-/angularjs-rails-resource-2.1.0.tgz","integrity":"sha512-lhttiTZK0vgML+ryl8UPQ2/PvxlOO9CeOLdMf7bXRVbdOvQQoQVfExLbD0Dx4KT8EOQEZcYon9aYtylhNS92aw==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIGqOoMSvrSf6Cxr2ki1CFCeW9rCjsyCL3dml3mcp+tnyAiEAgHxXC/lc0/tVSu6HvmjycSmhHGle28NEipQw1Az7rDU="}]},"_npmOperationalInternal":{"host":"packages-12-west.internal.npmjs.com","tmp":"tmp/angularjs-rails-resource-2.1.0.tgz_1458507686006_0.5445858684834093"},"directories":{}},"2.2.2":{"name":"angularjs-rails-resource","description":"A resource factory inspired by $resource from AngularJS","version":"2.2.2","main":"angularjs-rails-resource.min.js","homepage":"https://github.com/FineLinePrototyping/angularjs-rails-resource.git","author":"","repository":{"type":"git","url":"git+https://github.com/FineLinePrototyping/angularjs-rails-resource.git"},"keywords":["angular","resources"],"dependencies":{"angular":"^1.0"},"devDependencies":{"grunt":"~0.4.1","grunt-contrib-jshint":"~0.6.0","grunt-contrib-uglify":"~0.2.2","grunt-contrib-concat":"~0.3.0","grunt-contrib-copy":"~0.4.1","grunt-contrib-clean":"~0.5.0","grunt-contrib-watch":"~0.5.1","grunt-contrib-compress":"~0.5.2","grunt-bump":"~0.0.13","karma":"~0.10","karma-jasmine":"~0.1","karma-chrome-launcher":"~0.1","karma-phantomjs-launcher":"~0.1","karma-junit-reporter":"~0.1","q":"~0.9.2","q-io":"~1.10.6","qq":"~0.3.5"},"scripts":{"test":"karma start --single-run --browsers PhantomJS"},"licenses":[{"type":"MIT","url":"https://github.com/FineLinePrototyping/angularjs-rails-resource.js/blob/master/LICENSE"}],"gitHead":"3d3ff02df726cd56953395a558316e28b975804b","bugs":{"url":"https://github.com/FineLinePrototyping/angularjs-rails-resource/issues"},"_id":"angularjs-rails-resource@2.2.2","_shasum":"cb9ab72b514e40424ce51d391659ee128730f2d3","_from":".","_npmVersion":"2.11.3","_nodeVersion":"0.12.7","_npmUser":{"name":"tpodom","email":"tommy.odom@gmail.com"},"maintainers":[{"name":"tpodom","email":"tommy.odom@gmail.com"}],"dist":{"shasum":"cb9ab72b514e40424ce51d391659ee128730f2d3","tarball":"https://registry.npmjs.org/angularjs-rails-resource/-/angularjs-rails-resource-2.2.2.tgz","integrity":"sha512-rpPCqZ3zaKsN3541O60Ico9Q8Go2VlDx5dWkURs/yC3i4J6ZiGkmFO9L+p6OoWG8qQRcNmqzurvsZgSc1p9RnQ==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIESkxUBj4W9cIIl/KsmHei0qXnOw2FlZLzzLUqtUbjSbAiEA6mY+wwn3htii51ul8WZVB4BfJocPEt6jKlkNs04qwiw="}]},"_npmOperationalInternal":{"host":"packages-16-east.internal.npmjs.com","tmp":"tmp/angularjs-rails-resource-2.2.2.tgz_1475458315566_0.4996984957251698"},"directories":{}},"2.3.0":{"name":"angularjs-rails-resource","description":"A resource factory inspired by $resource from AngularJS","version":"2.3.0","main":"angularjs-rails-resource.min.js","homepage":"https://github.com/FineLinePrototyping/angularjs-rails-resource.git","author":"","repository":{"type":"git","url":"git+https://github.com/FineLinePrototyping/angularjs-rails-resource.git"},"keywords":["angular","resources"],"dependencies":{"angular":"^1.3"},"devDependencies":{"angular-mocks":"^1.3","grunt":"~0.4.1","grunt-bump":"~0.0.13","grunt-contrib-clean":"~0.5.0","grunt-contrib-compress":"~0.5.2","grunt-contrib-concat":"~0.3.0","grunt-contrib-copy":"~0.4.1","grunt-contrib-jshint":"~0.6.0","grunt-contrib-uglify":"~0.2.2","grunt-contrib-watch":"~0.5.1","karma":"~2.0","karma-chrome-launcher":"~2.2","karma-jasmine":"~0.1","karma-junit-reporter":"~1.2","karma-phantomjs-launcher":"~1.0","phantomjs-prebuilt":">=2","q":"~0.9.2","q-io":"~1.10.6","qq":"~0.3.5"},"scripts":{"test":"PHANTOMJS_BIN=./node_modules/.bin/phantomjs ./node_modules/.bin/karma start --single-run --browsers PhantomJS"},"licenses":[{"type":"MIT","url":"https://github.com/FineLinePrototyping/angularjs-rails-resource.js/blob/master/LICENSE"}],"gitHead":"95de6e73e3d40604c4d7fb9c409b7a62f42acdc0","bugs":{"url":"https://github.com/FineLinePrototyping/angularjs-rails-resource/issues"},"_id":"angularjs-rails-resource@2.3.0","_npmVersion":"5.6.0","_nodeVersion":"8.9.4","_npmUser":{"name":"tpodom","email":"tommy.odom@gmail.com"},"maintainers":[{"name":"tpodom","email":"tommy.odom@gmail.com"}],"dist":{"integrity":"sha512-INpbmMpUgzkDgs8ZlWqUtDuYQl7ZepDCqL/WVoW0DhQozD3o5Vh6M8FIy9Lnk3Sa8tIfKg20NTqk3GPr6AQhgQ==","shasum":"da28b3b1820bcd8a377d22b9e2e99e2c35e57ef0","tarball":"https://registry.npmjs.org/angularjs-rails-resource/-/angularjs-rails-resource-2.3.0.tgz","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIDCFdvk7908iwW6Z8TObeuZ7MBdVS4nAvRPzVcXocYOkAiAa40OJ8G5K4Syrjw2vqXeXkcEA3mJjWjIjlawB61iwjQ=="}]},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/angularjs-rails-resource-2.3.0.tgz_1517164921519_0.357981184264645"},"directories":{}},"2.3.1":{"name":"angularjs-rails-resource","description":"A resource factory inspired by $resource from AngularJS","version":"2.3.1","main":"dist/angularjs-rails-resource.min.js","homepage":"https://github.com/FineLinePrototyping/angularjs-rails-resource.git","author":"","repository":{"type":"git","url":"git+https://github.com/FineLinePrototyping/angularjs-rails-resource.git"},"keywords":["angular","resources"],"dependencies":{"angular":"^1.3"},"devDependencies":{"angular-mocks":"^1.3","grunt":"~0.4.1","grunt-bump":"~0.8.0","grunt-contrib-clean":"~0.5.0","grunt-contrib-compress":"~0.5.2","grunt-contrib-concat":"~0.3.0","grunt-contrib-copy":"~0.4.1","grunt-contrib-jshint":"~0.6.0","grunt-contrib-uglify":"~3.3.0","karma":"~2.0","karma-chrome-launcher":"~2.2","karma-jasmine":"~0.1","karma-junit-reporter":"~1.2","karma-phantomjs-launcher":"~1.0","phantomjs-prebuilt":">=2","q":"~0.9.2","q-io":"~1.10.6","qq":"~0.3.5"},"scripts":{"test":"PHANTOMJS_BIN=./node_modules/.bin/phantomjs ./node_modules/.bin/karma start --single-run --browsers PhantomJS"},"licenses":[{"type":"MIT","url":"https://github.com/FineLinePrototyping/angularjs-rails-resource.js/blob/master/LICENSE"}],"gitHead":"1edf9a4d924b060e62ed7a44041dea00898b0a3b","bugs":{"url":"https://github.com/FineLinePrototyping/angularjs-rails-resource/issues"},"_id":"angularjs-rails-resource@2.3.1","_npmVersion":"5.6.0","_nodeVersion":"8.9.4","_npmUser":{"name":"tpodom","email":"tommy.odom@gmail.com"},"maintainers":[{"name":"tpodom","email":"tommy.odom@gmail.com"}],"dist":{"integrity":"sha512-qA3WQT4kv7RvSgHj5v2pg8NL9cgFQ7g1NkwaBzVeLCsKI6UigHuR/CDr5pDtYcPk9aKKKW5lVWemoeAQw5jW2w==","shasum":"8fa1ef079c2084cb3e8a1d71106b3c5092785fe1","tarball":"https://registry.npmjs.org/angularjs-rails-resource/-/angularjs-rails-resource-2.3.1.tgz","fileCount":39,"unpackedSize":808185,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCZocjOod5ZMGraDEUcfjRUsRXf4sMoSxxIkR/zlBj2nAIhAIEC+eFdOf10tuNJhmclRq2jnU+M/1nt1v/dRyGZ6pft"}]},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/angularjs-rails-resource_2.3.1_1518376289189_0.41048855954194474"},"_hasShrinkwrap":false}},"readme":"# AngularJS Rails Resource\n[![Build Status](https://travis-ci.org/FineLinePrototyping/angularjs-rails-resource.png)](https://travis-ci.org/FineLinePrototyping/angularjs-rails-resource)\n\nA resource factory inspired by $resource from AngularJS and [Misko's recommendation](http://stackoverflow.com/questions/11850025/recommended-way-of-getting-data-from-the-server).\n\n## Differences from $resource\nThis library is not a drop in replacement for $resource.  There are significant differences that you should be aware of:\n\n1.  <code>get</code> and <code>query</code> return [$q promises](http://docs.angularjs.org/api/ng.$q), not an instance or array that will be populated.  To gain access to the results you\nshould use the promise <code>then</code> function.\n2.  By default we perform root wrapping and unwrapping (if wrapped) when communicating with the server.\n3.  By default we convert attribute names between underscore and camel case.\n\n## FAQs\n### How come I can't iterate the array returned from query?\nWe don't return an array.  We return promises not arrays or objects that get filled in later.\n\nIf you need access to the array in your JS code you can use the promise <code>then</code> function:\n````javascript\nBook.query({title: 'Moby Dick'}).then(function (books) {\n    $scope.books = books;\n});\n````\n\n### I like underscores, how can I turn off the name conversion?\nYou can inject the <code>railsSerializerProvider</code> into your application config function and override the <code>underscore</code>\nand <code>camelize</code> functions:\n````javascript\nangular.module('app').config([\"railsSerializerProvider\", function(railsSerializerProvider) {\n    railsSerializerProvider.underscore(angular.identity).camelize(angular.identity);\n}]);\n````\n\n## Installation\n### Rails Asset Pipeline\nAdd this line to your application's Gemfile to use the latest stable version:\n```ruby\ngem 'angularjs-rails-resource', '~> 2.0.0'\n```\n\nInclude the javascript somewhere in your asset pipeline:\n```javascript\n//= require angularjs/rails/resource\n```\n\nTo add extensions just add additional requires:\n```javascript\n//= require angularjs/rails/resource/extensions/snapshots\n```\n### JavaScript package managers\n\nInstall via [npm](https://www.npmjs.com/package/angularjs-rails-resource): `npm install angularjs-rails-resource`\n\nInstall via [Bower](http://bower.io): `bower install angularjs-rails-resource --save`\n\n### Standalone\nIf you aren't using the Rails asset pipeline you can download the combined\n[angularjs-rails-resource.js](https://github.com/FineLinePrototyping/dist-angularjs-rails-resource/blob/master/angularjs-rails-resource.js)\nor [angularjs-rails-resource.min.js](https://github.com/FineLinePrototyping/dist-angularjs-rails-resource/blob/master/angularjs-rails-resource.min.js).\n\nYou can also use [Bower](http://bower.io/) to install <code>angularjs-rails-resource</code>.\n\n## Branching and Versioning\nAs much as possible we will try to adhere to the [SemVer](http://semver.org/) guidelines on release numbering.\n\nThe master branch may contain work in progress and should not be considered stable.\n\nRelease branches should remain stable but it is always best to rely on the ruby gem release versions as the most stable versions.\n\n## Changes\nMake sure to check the [CHANGELOG](CHANGELOG.md) for any breaking changes between releases.\n\n## Usage\nThere are a lot of different ways that you can use the resources and we try not to force you into any specific pattern.\nAll of the functionality is packed in an AngularJS module named \"rails\" so make sure that your modules depend on that module\nfor the dependency injection to work properly.\n\nThere are more examples available in [EXAMPLES.md](EXAMPLES.md).\n\n### Defining Resources\nThere are multiple ways that you can set up define new resources in your application.\n\n#### railsResourceFactory\nSimilar to $resource, we provide a <code>railsResourceFactory(config)</code> function that takes a config object with the configuration\nsettings for the new resource.  The factory function returns a new class that is extended from RailsResource.\n\n```javascript\nangular.module('book.services', ['rails']);\nangular.module('book.services').factory('Book', ['railsResourceFactory', function (railsResourceFactory) {\n    return railsResourceFactory({\n        url: '/books',\n        name: 'book'\n    });\n}]);\n```\n\n#### RailsResource extension\nWe also expose the RailsResource as base class that you can extend to create your own resource classes.  Extending the RailsResource class\ndirectly gives you a bit more flexibility to add custom constructor code.  There are probably ten different ways to extend the class but\nthe two that we intend to be used are through CoffeeScript or through the same logic that the factory function uses.\n\n##### CoffeeScript\nTo allow better integration with CoffeeScript, we expose the RailsResource as a base class that can be extended to create\nresource classes.  When extending RailsResource you should use the <code>@configure</code> function to set configuration\nproperties for the resource.  You can call <code>@configure</code> multiple times to set additional properties as well.\n\n````coffeescript\nclass Book extends RailsResource\n  @configure url: '/books', name: 'book'\n\nclass Encyclopedia extends Book\n  @configure url: '/encyclopedias', name: 'encyclopedia'\n````\n\n**NOTE:** Always call <code>@configure()</code> in subclasses, even when no configuration is required.\nThis is important to prevent overriding the parent's configuration with interceptors, etc (especially when using a module mixin pattern).\n\n##### JavaScript\nSince the purpose of exposing the RailsResource was to allow for CoffeeScript users to create classes from it the JavaScript way\nis basically just the same as the generated CoffeeScript code.  The <code>RailsResource.extendTo</code> function is a modification\nof the <code>__extends</code> function that CoffeeScript generates.\n\n````javascript\nfunction Resource() {\n    Resource.__super__.constructor.apply(this, arguments);\n}\n\nRailsResource.extendTo(Resource);\nResource.configure(config);\n````\n##### ES6\nThe code currently does not export any module information but it can be imported using the 'load with side-effects' method.\nThis efectively runs through the code and makes the whole module available. Because we don't have an export to assign \nthe name 'rails' to a variable, we call in the angular module as a string, for example :\n````javascript\n// Import angular\nimport angular                  from 'angular';\nimport 'angular-animate'\nimport 'angular-aria'\n// Materail Design lib\nimport material                 from 'angular-material';\n// Router\nimport angularUIRouter          from 'angular-ui-router';\nimport ngTokenAuth              from 'ng-token-auth';\n// Note no 'from'\nimport  'angularjs-rails-resource';\n\nimport Configurations           from './configuration/module';\nimport SignIn                   from './devise/signIn/module';\nimport Models                   from './model/module';\n\nconst testAppModule = angular.module( 'testApp',\n    [   material,\n        ngTokenAuth,\n        ngStorage.name,\n        angularUIRouter,\n        'rails'\n        ])\n````\nIf you use ES6 classes to set up the model, the railsResourceFactory should be returned from the constructor, for example :\n\n````javascript\nclass Client {\n    constructor(railsResourceFactory,){\n        return railsResourceFactory({\n            url: \"/clients\",\n            name: \"client\"\n        });\n    }\n    clientMethod1(){\n        \n    };\n    \n    clientMethod2(){\n        \n    };\n\n}\n\nClient.$inject = ['railsResourceFactory'];\n\nexport default Client\n````\nThe model classes can then be gathered up in a separate module.js or index.js file, for example :\n````javascript\n\nimport Client               from './Client'\nimport User                 from './User'\nimport Blog                 from './Blog'\n\nexport default angular\n    .module('model', [])\n    .service('Client', Client)\n    .service('User', User)\n    .service('Blog', Blog)\n````\n\n\n### Using Resources\n```javascript\nangular.module('book.controllers').controller('BookShelfCtrl', ['$scope', 'Book', function ($scope, Book) {\n    $scope.searching = true;\n    $scope.books = [];\n\n    // Find all books matching the title\n    Book.query({ title: title }).then(function (results) {\n        $scope.books = results;\n        $scope.searching = false;\n    }, function (error) {\n        // do something about the error\n        $scope.searching = false;\n    });\n\n    // Find a single book and update it\n    Book.get(1234).then(function (book) {\n        book.lastViewed = new Date();\n        book.update();\n    });\n\n    // Create a book and save it\n    new Book({\n        title: 'Gardens of the Moon',\n        author: 'Steven Erikson',\n        isbn: '0-553-81957-7'\n    }).create();\n}]);\n```\n\n### Custom Serialization\nWhen defining a resource, you can pass a custom [serializer](#serializers) using the <code>serializer</code> configuration option to\nalter the behavior of the object serialization.\n```javascript\nAuthor = railsResourceFactory({\n    url: '/authors',\n    name: 'author',\n    serializer: railsSerializer(function () {\n        this.exclude('birthDate', 'books');\n        this.nestedAttribute('books');\n        this.resource('books', 'Book');\n    })\n});\n```\nYou can also specify a serializer as a factory and inject it as a dependency.\n```javascript\nangular.module('rails').factory('BookSerializer', function (railsSerializer) {\n    return railsSerializer(function () {\n        this.exclude('publicationDate', 'relatedBooks');\n        this.rename('ISBN', 'isbn');\n        this.nestedAttribute('chapters', 'notes');\n        this.serializeWith('chapters', 'ChapterSerializer');\n        this.add('numChapters', function (book) {\n            return book.chapters.length;\n        });\n    });\n});\n\nBook = railsResourceFactory({\n    url: '/books',\n    name: 'book',\n    serializer: 'BookSerializer'\n});\n```\n\n\n### Config Options\n\nThe following configuration options are available for customizing resources.  Each of the configuration options can be passed as part of an object\nto the <code>railsResourceFactory</code> function or to the resource's <code>configure</code> function.  The <code>configure</code> function\ndefined on the resource can be called multiple times to adjust properties as needed.\n\n * **url** - This is the url of the service.  See [Resource URLs](#resource-urls) below for more information.\n * **rootWrapping** - (Default: true) Turns on/off root wrapping on JSON (de)serialization.\n * **name** - This is the name used for root wrapping when dealing with singular instances.\n * **pluralName** *(optional)* - If specified this name will be used for unwrapping array results.  If not specified then the serializer's [pluralize](#serializers) method is used to calculate\n        the plural name from the singular name.\n * **idAttribute** *(optional)* - (Default: 'id') Configures what field on the record represents the unique identifier.\n * **httpConfig** *(optional)* - By default we will add the following headers to ensure that the request is processed as JSON by Rails. You can specify additional http config options or override any of the defaults by setting this property.  See the [AngularJS $http API](http://docs.angularjs.org/api/ng.$http) for more information.\n     * **headers**\n         * **Accept** - application/json\n         * **Content-Type** - application/json\n * **defaultParams** *(optional)* - If the resource expects a default set of query params on every call you can specify them here.\n * **underscoreParams** *(optional)* - Controls whether or not query parameters are converted from camel case to underscore.\n * **updateMethod** *(optional)* - Allows overriding the default HTTP method (PUT) used for update.  Valid values are \"post\", \"put\", or \"patch\".\n * **serializer** *(optional)* - Allows specifying a custom [serializer](#serializers) to configure custom serialization options.\n * **fullResponse** *(optional)* - When set to true promises will return full $http responses instead of just the response data.\n * **singular** - (Default: false) Treat this as a [singular resource](http://guides.rubyonrails.org/routing.html#singular-resources).\n * **interceptors** *(optional)* - See [Interceptors](#interceptors)\n * **extensions** *(optional)* - See [Extensions](#extensions)\n\n**Deprecated:**\n * **requestTransformers** *(optional)* - See [Transformers / Interceptors](#transformers--interceptors)\n * **responseInterceptors** *(optional)* - See [Transformers / Interceptors](#transformers--interceptors)\n * **afterResponseInterceptors** *(optional)* - See [Transformers / Interceptors](#transformers--interceptors)\n\n**NOTE:** The names should be specified using camel case when using the key transformations because that happens before the root wrapping by default.\nFor example, you should specify \"publishingCompany\" and \"publishingCompanies\" instead of \"publishing_company\" and \"publishing_companies\".\n\n### Provider Configuration\n<code>RailsResource</code> can be injected as <code>RailsResourceProvider</code> into your app's config method to configure defaults for all the resources application-wide.\nThe individual resource configuration takes precedence over application-wide default configuration values.\nEach configuration option listed is exposed as a method on the provider that takes the configuration value as the parameter and returns the provider to allow method chaining.\n\n* rootWrapping - {function(boolean):RailsResourceProvider}\n* httpConfig - {function(object):RailsResourceProvider}\n* defaultParams - {function(object):RailsResourceProvider}\n* underscoreParams - {function(boolean):RailsResourceProvider}\n* updateMethod - {function(boolean):RailsResourceProvider}\n* fullResponse - {function(boolean):RailsResourceProvider}\n* extensions - {function(...string):RailsResourceProvider}\n\nFor example, to turn off the root wrapping application-wide and set the update method to PATCH:\n\n````javascript\napp.config(function (RailsResourceProvider) {\n    RailsResourceProvider.rootWrapping(false).updateMethod('patch');\n);\n````\n\n## Resource URLs\nThe URL can be specified as one of three ways:\n\n 1. function (context) - You can pass your own custom function that converts a context variable into a url string\n\n 2. basic string - A string without any expression variables will be treated as a base URL and assumed that instance requests should append id to the end.\n\n 3. AngularJS expression - An expression url is evaluated at run time based on the given context for non-instance methods or the instance itself. For example, given the url expression: `/stores/{{storeId}}/items/{{id}}`\n\n```javascript\nItem.query({category: 'Software'}, {storeId: 123}) // would generate a GET to /stores/123/items?category=Software\nItem.get({storeId: 123, id: 1}) // would generate a GET to /stores/123/items/1\n\nnew Item({store: 123}).create() // would generate a POST to /stores/123/items\nnew Item({id: 1, storeId: 123}).update() // would generate a PUT to /stores/123/items/1\n```\n\n## Promises\n[$http documentation](http://docs.angularjs.org/api/ng.$http) describes the promise data very well so I highly recommend reading that.\n\nIn addition to the fields listed in the $http documentation an additional field named originalData is added to the response\nobject to keep track of what the field was originally pointing to.  The originalData is not a deep copy, it just ensures\nthat if response.data is reassigned that there's still a pointer to the original response.data object.\n\n### Canceling Requests\nThe promises returned from this library have an extra ```abort``` function defined that will allow you to cancel an outstanding request. Canceling the request will trigger timeout on ```$http``` which will in turn reject the outstanding promise. We wrap the ```$q``` promise to ensure that every time you chain the promise we re-add the ```abort``` function to the new promise.\n\nFor example, the following code would abort the query request after the 5 second timeout:\n```javascript\nvar promise = Item.query({category: 'Software'}, {storeId: 123});\n$timeout(promise.abort, 5000);\n```\n\n## Resource Methods\nRailsResources have the following class methods available.\n\n### Class Methods\n* Constructor(data) - The Resource object can act as a constructor function for use with the JavaScript <code>new</code> keyword.\n    * **data** {object} (optional) - Optional data to set on the new instance\n\n* configure(options) - Change one or more configuration option for a resource.\n\n* extendTo(child) - Modifies the child to be a subclass of a RailsResource.  This can be used to create multiple levels of inheritance. See [RailsResource extension](#RailsResource-extension) for more information\n\n* include(...module) - Includes a mixin module into the resource.  See [Mixins](#mixins) for more information\n\n* setUrl(url) - Updates the url for the resource, same as calling <code>configure({url: url})</code>\n\n* $url(context, path) - Returns the resource URL using the given context with the optional path appended if provided.\n    * **context** {*} - The context to use when building the url.  See [Resource URLs](#resource-urls) above for more information.\n    * **path** {string} (optional) - A path to append to the resource's URL.\n    * **returns** {string} - The resource URL\n\n* query(queryParams, context) - Executes a GET request against the resource's base url (e.g. /books).\n    * **query params** {object} (optional) - An map of strings or objects that are passed to $http to be turned into query parameters\n    * **context** {*} (optional) - A context object that is used during url evaluation to resolve expression variables\n    * **returns** {promise} - A promise that will be resolved with an array of new Resource instances\n\n* get(context) - Executes a GET request against the resource's url (e.g. /books/1234).\n    * **context** {*} - A context object that is used during url evaluation to resolve expression variables.  If you are using a basic url this can be an id number to append to the url.\n    * **returns** {promise} A promise that will be resolved with a new instance of the Resource\n\n* $get(customUrl, queryParams) - Executes a GET request against the given URL.\n    * **customUrl** {string} - The url to GET\n    * **queryParams** {object} (optional) - The set of query parameters to include in the GET request\n    * **returns** {promise} A promise that will be resolved with a new Resource instance (or instances in the case of an array response).\n\n* $post/$put/$patch(customUrl, data, resourceConfigOverrides, queryParams) - Serializes the data parameter using the Resource's normal serialization process and submits the result as a POST / PUT / PATCH to the given URL.\n    * **customUrl** {string} - The url to POST / PUT / PATCH to\n    * **data** {object} - The data to serialize and POST / PUT / PATCH\n    * **resourceConfigOverrides** {object} (optional) - An optional set of RailsResource configuration option overrides to use for this request. Root wrapping and serialization for the request data can be bypassed using the `skipRequestProcessing` flag. This also bypasses the entire pre-request [interceptor](#interceptors) chain.\n    * **queryParams** {object} (optional) - The set of query parameters to include in the request\n    * **returns** {promise} A promise that will be resolved with a new Resource instance (or instances in the case of an array response).\n\n* $delete(customUrl, queryParams) - Executes a DELETE to a custom URL.  The main difference between this and $http.delete is that a server response that contains a body will be deserialized using the normal Resource deserialization process.\n    * **customUrl** {string} - The url to DELETE to\n    * **queryParams** {object} (optional) - The set of query parameters to include in the DELETE request\n    * **returns** {promise} A promise that will be resolved with a new Resource instance (or instances in the case of an array response) if the server includes a response body.\n\n* $http(httpConfig, context, resourceConfigOverrides) - Executes an HTTP operation specified by the config.  The request data is serialized and root wrapped (if configured).  The response data is unwrapped (if configured) and deserialized and copied to the context object if specified.\n  * **httpConfig** {object} - Standard $http config object.\n  * **context** {object} - The instance that the operation is being run against.\n  * **resourceConfigOverrides** {object} (optional) - An optional set of RailsResource configuration option overrides to use for this request. Root wrapping and serialization for the request data can be bypassed using the `skipRequestProcessing` flag. This also bypasses the entire pre-request [interceptor](#interceptors) chain.\n\n* addInterceptor(interceptor) - Adds an interceptor to the resource class.\n  * **interceptor** {object | string} - See [Interceptors](#interceptors) for details of object format.\n\n* intercept(phase, callback) - Creates an interceptor for the specified phase and adds it to the resource's interceptor list.  The callback function will be executed when the interceptor phase is run.  If the callback function returns a value that will take the place of the value going forward in the promise chain.\n  * **phase** {string} - The interceptor phase, see [Interceptors](#interceptors) for a list of phases.\n  * **callback** {function(value, resourceConstructor, context)} - The callback function to execute.  The value parameter varies based on the phase.  See [Interceptors](#interceptors) for details.  The resourceConstructor is the resource's constructor function.  The context is the resource instance that operation is running against which may be undefined.\n* interceptBeforeRequest(callback) - Shortcut for intercept('beforeRequest', callback)\n* interceptBeforeRequestWrapping(callback) - Shortcut for intercept('beforeRequestWrapping', callback)\n* interceptRequest(callback) - Shortcut for intercept('request', callback)\n* interceptBeforeResponse(callback) - Shortcut for intercept('beforeResponse', callback)\n* interceptBeforeResponseDeserialize(callback) - Shortcut for intercept('beforeResponseDeserialize', callback)\n* interceptResponse - Shortcut for intercept('response', callback)\n* interceptAfterResponse - Shortcut for intercept('afterResponse', callback)\n\n**Deprecated**\n* beforeRequest(fn(data, resource)) - See [Interceptors](#interceptors) for more information.  The function is called prior to the serialization process so the data\npassed to the function is still a Resource instance as long as another transformation function has not returned a new object to serialize.\n    * fn(data, resource) {function} - The function to add as a transformer.\n        * **data** {object} - The data being serialized\n        * **resource** {Resource class} - The Resource class that is calling the function\n        * **returns** {object | undefined} - If the function returns a new object that object will instead be used for serialization.\n\n* beforeResponse(fn(data, resource, context)) - See [Interceptors](#interceptors) for more information.  The function is called after the response data has been unwrapped and deserialized.\n    * fn(data, resource, context) {function} - The function to add as an interceptor\n        * **data** {object} - The data received from the server\n        * **resource** {Resource function} - The Resource constructor that is calling the function\n        * **context** {Resource|undefined} - The Resource instance that is calling the function or undefined if called from a class level method (get, query).\n\n* afterResponse(fn(data, resource, context)) - See [Interceptors](#interceptors) for more information.  This function is called after all internal processing and beforeResponse callbacks have been completed.\n    * fn(data, resource) {function} - The function to add as an interceptor\n        * **data** {object} - The result, either an array of resource instances or a single resource instance.\n        * **resource** {Resource function} - The Resource constructor that is calling the function\n\n* afterDeserialize(fn(data, resource, context)) - See [Interceptors](#interceptors) for more information.  This function is called after a resource (including assocations) has been deserialized.\n    * fn(data, resource) {function} - The function to add as an interceptor\n        * **data** {object} - The result, either an array of resource instances or a single resource instance.\n        * **resource** {Resource function} - The Resource constructor that is calling the function\n\n### Instance Methods\nThe instance methods can be used on any instance (created manually or returned in a promise response) of a resource.\nAll of the instance methods will update the instance in-place on response and will resolve the promise with the current instance.\n\n* $url(path) - Returns this Resource instance's URL with the optional path appended if provided.\n    * **path** {string} (optional) - A path to append to the resource's URL.\n\n* get() - Refreshes the instance from the server.\n    * **returns** {promise} - A promise that will be resolved with the instance itself\n\n* create() - Submits the resource instance to the resource's base URL (e.g. /books) using a POST\n    * **returns** {promise} - A promise that will be resolved with the instance itself\n\n* update() - Submits the resource instance to the resource's URL (e.g. /books/1234) using a PUT\n    * **returns** {promise} - A promise that will be resolved with the instance itself\n\n* save() - Calls <code>create</code> if <code>isNew</code> returns true, otherwise it calls <code>update</code>.\n\n* remove(), delete() - Executes an HTTP DELETE against the resource's URL (e.g. /books/1234)\n    * **returns** {promise} - A promise that will be resolved with the instance itself\n\n* $http(httpConfig, resourceConfigOverrides) - Executes class method $http with the resource instance as the operation context.\n\n* $post(customUrl, context, queryParams), $put(customUrl, context, queryParams), $patch(customUrl, context, queryParams) - Serializes and submits the instance using an HTTP POST/PUT/PATCH to the given URL.\n    * **customUrl** {string} - The url to POST / PUT / PATCH to\n    * **context** {object} - The instance that the operation is being run against.\n    * **queryParams** {object} (optional) - The set of query parameters to include in the POST / PUT / PATCH request\n    * **returns** {promise} - A promise that will be resolved with the instance itself\n\n* $delete(customUrl, queryParams) - Executes a DELETE to a custom URL.  The main difference between this and $http.delete is that a server response that contains a body will be deserialized using the normal Resource deserialization process.\n    * **customUrl** {string} - The url to DELETE to\n    * **queryParams** {object} (optional) - The set of query parameters to include in the DELETE request\n    * **returns** {promise} - A promise that will be resolved with the instance itself\n\n\n## Serializers\nOut of the box, resources serialize all available keys and transform key names between camel case and underscores to match Ruby conventions.\nHowever, that basic serialization often isn't ideal in every situation.  With the serializers users can define customizations\nthat dictate how serialization and deserialization is performed.  Users can: rename attributes, specify extra attributes, exclude attributes\nwith the ability to exclude all attributes by default and only serialize ones explicitly allowed, specify other serializers to use\nfor an attribute and even specify that an attribute is a nested resource.\n\nAngularJS automatically excludes all attribute keys that begin with $ in their toJson code.\n\n### railsSerializer\n* railsSerializer(options, customizer) - Builds a Serializer constructor function using the configuration options specified.\n    * **options** {object} (optional) - Configuration options to alter the default operation of the serializers.  This parameter can be excluded and the\n    customizer function specified as the first argument instead.\n    * **customizer** {function} (optional) - A function that will be called to customize the serialization logic.\n    * **returns** {Serializer} - A Serializer constructor function\n\n### Configuration\nThe <code>railsSerializer</code> function takes a customizer function that is called on create within the context of the constructed Serializer.\nFrom within the customizer function you can call customization functions that affect what gets serialized and how or override the default options.\n\n#### Configuration Options\nSerializers have the following available configuration options:\n* underscore - (function) Allows users to supply their own custom underscore conversion logic.\n    * **default**: RailsInflector.underscore\n    * parameters\n        * **attribute** {string} - The current name of the attribute\n    * **returns** {string} - The name as it should appear in the JSON\n* camelize - (function) Allows users to supply their own custom camelization logic.\n    * **default**: RailsInflector.camelize\n    * parameters\n        * **attribute** {string} - The name as it appeared in the JSON\n    * **returns** {string} - The name as it should appear in the resource\n* pluralize - (function) Allows users to supply their own custom pluralization logic.\n    * default: RailsInflector.pluralize\n    * parameters\n        * **attribute** {string} - The name as it appeared in the JSON\n    * **returns** {string} - The name as it should appear in the resource\n* exclusionMatchers {array} - An list of rules that should be applied to determine whether or not an attribute should be excluded.  The values in the array can be one of the following types:\n    * string - Defines a prefix that is used to test for exclusion\n    * RegExp - A custom regular expression that is tested against the attribute name\n    * function - A custom function that accepts a string argument and returns a boolean with true indicating exclusion.\n\n#### Provider Configuration\n<code>railsSerializer</code> can be injected as <code>railsSerializerProvider</code> into your app's config method to configure defaults for all the serializers application-wide.\nEach configuration option listed is exposed as a method on the provider that takes the configuration value as the parameter and returns the provider to allow method chaining.\n\n* underscore - {function(fn):railsSerializerProvider}\n* camelize - {function(fn):railsSerializerProvider}\n* pluralize - {function(fn):railsSerializerProvider}\n* exclusionMatchers - {function(matchers):railsSerializerProvider}\n\n\n#### Customization API\nThe customizer function passed to the railsSerializer has available to it the following methods for altering the serialization of an object.  None of these methods support nested attribute names (e.g. <code>'books.publicationDate'</code>), in order to customize the serialization of the <code>books</code> objects you would need to specify a custom serializer for the <code>books</code> attribute.\n\n* exclude (attributeName...) - Accepts a variable list of attribute names to exclude from JSON serialization.  This has no impact on what is deserialized from the server.\n\n* only (attributeName...) - Accepts a variable list of attribute names that should be included in JSON serialization.  This has no impact on what is deserialized from the server.  Using this method will by default exclude all other attributes and only the ones explicitly included using <code>only</code> will be serialized.\n\n* rename (javascriptName, jsonName) - Specifies a custom name mapping for an attribute.  On serializing to JSON the <code>jsonName</code> will be used.  On deserialization, if <code>jsonName</code> is seen then it will be renamed as javascriptName in the resulting resource.  Right now it is still passed to underscore so you could do 'publicationDate' -> 'releaseDate' and it will still underscore as release_date.  However, that may be changed to prevent underscore from breaking some custom name that it doesn't handle properly.\n\n* nestedAttribute (attributeName...) - This is a shortcut for rename that allows you to specify a variable number of attributes that should all be renamed to <code><name>_attributes</code> to work with the Rails nested_attributes feature.  This does not perform any additional logic to accommodate specifying the <code>_destroy</code> property.\n\n* resource (attributeName, resource, serializer) - Specifies an attribute that is a nested resource within the parent object.  Nested resources do not imply nested attributes, if you want both you still have to specify call <code>nestedAttribute</code> as well.  A nested resource serves two purposes.  First, it defines the resource that should be used when constructing resources from the server.  Second, it specifies how the nested object should be serialized.  An optional third parameter <code>serializer</code> is available to override the serialization logic of the resource in case you need to serialize it differently in multiple contexts.\n\n* add (attributeName, value) - Allows custom attribute creation as part of the serialization to JSON.  The parameter <code>value</code> can be defined as function that takes a parameter of the containing object and returns a value that should be included in the JSON.\n\n* serializeWith (attributeName, serializer) - Specifies a custom serializer that should be used for the attribute.  The serializer can be specified either as a <code>string</code> reference to a registered service or as a Serializer constructor returned from <code>railsSerializer</code>\n\n* polymorphic (attributeName...) - Specifies a polymorphic association according to Rails' standards. Polymorphic associations have a <code>{name}_id</code> and <code>{name}_type</code> columns in the database. The <code>{name}_type</code> attribute will specify which resource will be used to serialize and deserialize the data.\n\n### Serializer Methods\nThe serializers are defined using mostly instance prototype methods.  For information on those methods please see the inline documentation.  There are however a couple of class methods that\nare also defined to expose underscore, camelize, and pluralize.  Those functions are set to the value specified by the configuration options sent to the serializer.\n\n## Interceptors\nThe entire request / response processing is configured as a [$q promise chain](http://docs.angularjs.org/api/ng.$q).  Interceptors allow inserting additional synchronous or asynchronous processing at various phases in the request / response cycle.  The flexibility of the synchronous or asynchronous promise resolution allows any number of customizations to be built.  For instance, on response you could load additional data before returning that the current response is complete.  Or, you could listen to multiple phases and set a flag that a save operation is in progress in <code>beforeRequest</code> and then in <code>afterResponse</code> and <code>afterResponseError</code> you could clear the flag.\n\nInterceptors are similar in design to the $http interceptors.  You can add interceptors via the <code>RailsResource.addInterceptor</code> method or by explicitly adding them to the <code>interceptors</code> array on the on the resource <code>config</code> object.  When you add the interceptor, you can add it using either the interceptor service factory name or the object reference.  An interceptor should contain a set of keys representing one of the valid phases and the callback function for the phase.\n\nThere are several phases for both request and response to give users and mixins more flexibility for exactly where they want to insert a customization.  Each phase also has a corresponding error phase which is the phase name appended with Error (e.g. beforeResponse and beforeResponseError).  The error phases receive the current rejection value which in most cases would be the error returned from $http.  Since these are $q promises, your interceptor can decide whether or not to propagate the error or recover from it.  If you want to propagate the error, you must return a <code>$q.reject(reason)</code> result.  Otherwise any value you return will be treated as a successful value to use for the rest of the chain.  For instance, in the <code>beforeResponseError</code> phase you could attempt to recover by using an alternate URL for the request data and return the new promise as the result.\n\nEach request phase interceptor is called with the $http config object, the resource constructor, and if applicable the resource instance.  The interceptor is free to modify the config or create a new one.  The interceptor function must return a valid $http config or a promise that will eventually resolve to a config object.\n\nThe valid request phases are:\n\n * beforeRequest: Interceptors are called prior to any data serialization or root wrapping.\n * beforeRequestError: Interceptors get called when a previous interceptor threw an error or resolved with a rejection.\n * beforeRequestWrapping: Interceptors are called after data serialization but before root wrapping.\n * beforeRequestWrappingError: Interceptors get called when a previous interceptor threw an error or resolved with a rejection.\n * request:  Interceptors are called after any data serialization and root wrapping have been performed.\n * requestError: Interceptors get called when a previous interceptor threw an error or resolved with a rejection.\n\nThe beforeResponse and response interceptors are called with the $http response object, the resource constructor, and if applicable the resource instance.  The afterResponse interceptors are typically called with the response data instead of the full response object unless the config option fullResponse has been set to true.  Like the request interceptor callbacks the response callbacks can manipulate the data or return new data.  The interceptor function must return\n\n The valid response phases are:\n\n * beforeResponse: Interceptors are called prior to any data processing.\n * beforeResponseError: Interceptors get called when a previous interceptor threw an error or resolved with a rejection.\n * beforeResponseDeserialize: Interceptors are called after root unwrapping but prior to data deserializing.\n * beforeResponseDeserializeError: Interceptors get called when a previous interceptor threw an error or resolved with a rejection.\n * response:  Interceptors are called after the data has been deserialized and root unwrapped but prior to the data being copied to the resource instance if applicable.\n * responseError: Interceptors get called when a previous interceptor threw an error or resolved with a rejection.\n * afterResponse:  Interceptors are called at the very end of the response chain after all processing\n      has been completed.  The value of the first parameter is one of the following:\n       - resource instance: When fullResponse is false and the operation was called on a resource instance.\n       - response data: When fullResponse is false and the operation was called on the resource class.\n       - $http response: When fullResponse is true\n * afterResponseError: Interceptors get called when a previous interceptor threw an error or resolved with a rejection.\n\n### Example Interceptor\n```javascript\nangular.module('rails').factory('saveIndicatorInterceptor', function () {\n    return {\n        'beforeRequest': function (httpConfig, resourceConstructor, context) {\n            if (context && (httpConfig.method === 'post' || httpConfig.method === 'put')) {\n                context.savePending = true;\n            }\n            return httpConfig;\n        },\n        'afterResponse': function (result, resourceConstructor, context) {\n            if (context) {\n                context.savePending = false;\n            }\n            return result;\n        },\n        'afterResponseError': function (rejection, resourceConstructor, context) {\n            if (context) {\n                context.savePending = false;\n            }\n            return $q.reject(rejection);\n        }\n    };\n});\n```\n\n## Transformers / Interceptors (**DEPRECATED**)\nThe transformers and interceptors can be specified using an array containing transformer/interceptor functions or strings\nthat can be resolved using Angular's DI.  The transformers / interceptors concept was prior to the [serializers](#serializers) but\nwe kept the API available because there may be use cases that can be accomplished with these but not the serializers.\n\n### Request Transformers\nTransformer functions are called to transform the data before we send it to $http for POST/PUT.\n\nA transformer function is called with two parameters:\n* data - The data that is being sent to the server\n* resource - The resource class that is calling the transformer\n\nA transformer function must return the data.  This is to allow transformers to return entirely new objects in place of the current data (such as root wrapping).\n\nThe resource also exposes a class method <code>beforeRequest(fn)</code> that accepts a function to execute and automatically wraps it as a transformer and appends it\nto the list of transformers for the resource class.  The function passed to <code>beforeRequest</code> is called with the same two parameters.  One difference\nis that the functions are not required to return the data, though they still can if they need to return a new object.  See [example](EXAMPLES.md#specifying-transformer).\n\n### Response Interceptors\nInterceptor functions utilize [$q promises](http://docs.angularjs.org/api/ng.$q) to process the data returned from the server.\n\nThe interceptor is called with the promise returned from $http and is expected to return a promise for chaining.  The promise passed to each\ninterceptor contains two additional properties:\n  * **resource** - The Resource constructor function for the resource calling the interceptor\n  * **context** - The Resource instance if applicable (create, update, delete) calling the interceptor\n\nEach interceptor promise is expected to return the response or a $q.reject.  See [Promises](#promises) for more information about the promise data.\n\nThe resource also exposes a class method <code>beforeResponse(fn)</code> that accepts a function to execute and automatically wraps it as an interceptor and appends it\nto the list of interceptors for the resource class.  Functions added with <code>beforeResponse</code> don't need to know anything about promises since they are automatically wrapped\nas an interceptor.\n\n### After Response Interceptors\nAfter response interceptors are called after all processing and response interceptors have completed.  An after response interceptor is analogous to\nchaining a promise after the resource method call but is instead for all methods.\n\nThe after response interceptors are called with the final processing promise and is expected to return a promise for chaining.  The promise is resolved\nwith the result of the operation which will be either a resource instance or an array of resource instances.  The promise passed to the interceptor\nhas the following additional property:\n * **resource** - The Resource constructor function for the resource calling the interceptor\n\nThe resource also exposes a class method <code>afterResponse(fn)</code> that accepts a function to execute and automatically wraps it as an interceptor and appends it\nto the list of after response interceptors for the resource class.  Functions added with <code>afterResponse</code> don't need to know anything about promises since they are automatically wrapped\nas an interceptor.\n\n## Mixins\nThe ability to add a [Mixin](http://en.wikipedia.org/wiki/Mixin) to a RailsResource is modeled after the example code in\nin the [Classes](http://arcturo.github.io/library/coffeescript/03_classes.html) chapter of [The Little Book on CoffeeScript](http://arcturo.github.io/library/coffeescript/index.html).\n\nRailsResource provides two methods:\n* **extend** - Add class properties / methods to the resource\n* **include** - Add instance properties / methods to the resource prototype chain\n\nWhen you call <code>extend</code> or <code>include</code> the mixin will be added to the resource.  If your mixin provides\none of the callback methods (<code>extended</code> or <code>included</code>) then those methods will be called when the mixin\nis added.  One additional change from the normal mixin behavior is that your mixins can implement an additional <code>configure</code>\nfunction that will be called whenever the resource's <code>configure</code> function is called.  That way the mixin can provide\nadditional configuration options.\n\n## Extensions\nExtensions are provided [mixins](#mixins) that follow specific naming pattern to make it easier to include them by a shortened name.\n\nThe available extension names are:\n * [snapshots](#snapshots) - RailsResourceSnapshotsMixin\n\nTo include an extension, you have to first include the extension in your project.\nYou then need to add the extension to the in one of the following ways to RailsResource:\n\n### Application-wide Resource Extensions\n<code>RailsResourceProvider.extensions</code> - adds the extension to all RailsResources within the application.\n````javascript\napp.config(function (RailsResourceProvider) {\n    RailsResourceProvider.extensions('snapshots');\n});\n````\n\n### Per-Resource Extensions\n#### Configuration Option\nThe <code>extensions</code> configuration option adds the extension to a single RailsResource\n\n##### JavaScript\n````javascript\nBook = railsResourceFactory({\n    url: '/books',\n    name: 'book',\n    extensions: ['snapshots']\n});\n````\n##### CoffeeScript\n````coffeescript\nclass Book extends RailsResource\n  @configure url: '/books', name: 'book', extensions: ['snapshots']\n````\n\n#### RailsResource.extend\nRailsResource.extend - explicitly include the extension as a module\n\n##### JavaScript\n````javascript\nBook = railsResourceFactory({ url: '/books', name: 'book' });\n// by name\nBook.extend('RailsResourceSnapshotsMixin');\n// or by injected reference\nBook.extend(RailsResourceSnapshotsMixin);\n````\n\n##### CoffeeScript\n\n````coffeescript\nclass Book extends RailsResource\n  @configure url: '/books', name: 'book'\n  @extend 'RailsResourceSnapshotsMixin'\n````\n\n### Snapshots\nSnapshots allow you to save off the state of the resource at a specific point in time and if need be roll back to one of the\nsaved snapshots and yes, you can create as many snapshots as you want.\n\nSnapshots serialize the resource instance and save off a copy of the serialized data in the <code>$$snapshots</code> array on the instance.\nIf you use a custom serialization options to control what is sent to the server you may want to consider whether or not you want to use\ndifferent serialization options.  If so, you can specify an specific serializer for snapshots using the <code>snapshotSerializer</code> configuration\noption.\n\nCalling <code>save</code>, <code>create</code>, <code>update</code>, or <code>delete</code>/<code>remove</code> on a resource instance\nwill remove all snapshots when the operation completes successfully.\n\n#### Configuration Options\n * **snapshotSerializer** *(optional)* - Allows specifying a custom [serializer](#serializers) to configure custom serialization options specific to [snapshot and rollback](#snapshots).\n\n\n#### Creating Snapshots\nCreating a snapshot is easy, just call the <code>snapshot</code> function.  You can pass an optional callback function to <code>snapshot</code> to perform\nadditional custom operations after the rollback is complete.   The callback function is specific to each snapshot version created so make sure you pass it every\ntime if it's a callback you always want called.\n\n#### Rolling back\nSo you want to undo changes to the resource?  There are two methods you can use to roll back the resource to a previous snapshot version <code>rollback</code>\nand <code>rollbackTo</code>.  Each method will:\n * Deserialize the snapshot data and update the resource instance with the new data.\n * Remove all snapshots newer than the version being rolled back to.\n * Call the rollback callback if it was specified on the <code>snapshot</code> in the context of the resource instance.\n\n##### rollback\n<code>rollback(numVersions)</code> allows you to roll back the resource.  If you do not specify <code>numVersions</code> then a resource is rolled back to the last\nsnapshot version.  <code>numVersions</code> can be used to roll back further than the last snapshot version based on the following rules:\n\n* When <code>numVersions</code> is undefined or 0 then a single version is rolled back.\n* When <code>numVersions</code> exceeds the stored number of snapshots then the resource is rolled back to the first snapshot version.\n* When <code>numVersions</code> is less than 0 then the resource is rolled back to the first snapshot version.\n* Otherwise, <code>numVersions</code> represents the nth version from the last snapshot version (similar to calling rollback <code>numVersions</code> times).\n\n##### rollbackTo\n<code>rollbackTo(snapshotVersion)</code> allows you to roll back the resource to a specific snapshot version.\n\n* When <code>snapshotVersion</code> is greater than the number of versions then the last snapshot version will be used.\n* When <code>snapshotVersion</code> is less than 0 then the resource will be rolled back to the first version.\n* Otherwise, the resource will be rolled back to the specific version specified.\n\n##### unsnappedChanges\n`unsnappedChanges()` checks to see if the resource has been changed since its last snapshot\n\n* If there are no snapshots, returns `true`\n* If all properties considered by `angular.equals` match the latest snapshot, returns `false`;\n  otherwise, returns `true`\n* (Note that `angular.equals` [does not consider $-prefixed properties](https://docs.angularjs.org/api/ng/function/angular.equals))\n\n## Tests\nThe tests are written using [Jasmine](http://pivotal.github.com/jasmine/) and are run using [Karma](https://github.com/karma-runner/karma).\n\nRunning the tests should be as simple as following the [instructions](https://github.com/karma-runner/karma)\n\n## Contributing\n\n1. Fork it\n2. Create your feature branch (`git checkout -b my-new-feature`)\n3. Commit your changes (`git commit -am 'Added some feature'`)\n4. Push to the branch (`git push origin my-new-feature`)\n5. Create new Pull Request\n\n## License\nCopyright (c) 2012 - 2017 [FineLine Prototyping, Inc.](http://www.finelineprototyping.com)\n\nMIT License\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n\"Software\"), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\nNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\nLIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\nOF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\nWITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n","maintainers":[{"name":"tpodom","email":"tommy.odom@gmail.com"}],"time":{"modified":"2022-06-13T03:03:06.223Z","created":"2016-03-20T21:01:28.330Z","2.1.0":"2016-03-20T21:01:28.330Z","2.2.2":"2016-10-03T01:31:56.848Z","2.3.0":"2018-01-28T18:42:02.646Z","2.3.1":"2018-02-11T19:11:30.319Z"},"homepage":"https://github.com/FineLinePrototyping/angularjs-rails-resource.git","keywords":["angular","resources"],"repository":{"type":"git","url":"git+https://github.com/FineLinePrototyping/angularjs-rails-resource.git"},"bugs":{"url":"https://github.com/FineLinePrototyping/angularjs-rails-resource/issues"},"readmeFilename":"README.md"}