angularjs-rails-resource 1.0.0.pre.2 → 1.0.0.pre.3

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: e088a0ef4c31ca6952015c7e5bf25e29a3aeffa6
4
- data.tar.gz: ceafd0fc62d19853922b36a79b3926cd1ca579c9
3
+ metadata.gz: f7ce09b68d048977e8091b90cd120e0f7836f183
4
+ data.tar.gz: 2c0eb42c1684eb64a5fd58e80a7adc8fed7e4e2f
5
5
  SHA512:
6
- metadata.gz: 8715afd2c22e4a5341512ba1845d83c6b5044cb6592dec4574fe530f908866ad9a48cc9f51b1fcfefe977bd30cf8661e5e39f2240c61ed9a0237be1cb81a6e28
7
- data.tar.gz: 93efebbbb2920fe2f2d6deb883bdfbe18cb8e5a720e93c946471deb1b9e8d6794820421e1dd4589179fc9643fb2c0eed90261458dbea030f05b291deda8f894c
6
+ metadata.gz: 6eb139ae046e2756eba924f354fbc386d752994ce43bbb67f5696f5c8567cc5ac49a125c7b687079c4766bce508dbd67dbc9c86097647e502daaf00952b01677
7
+ data.tar.gz: 56415e2fc32de4a5bd82db9cf0ece3ab680aa583bbb61a5df39bd2f8d14c95a2e74b3028c877da15f6fe648a86f6977937d1be9188d3971a4437d0ba295d3bf3
data/.gitignore CHANGED
@@ -18,4 +18,5 @@ tmp
18
18
  test_out
19
19
  atlassian-ide-plugin.xml
20
20
  node_modules
21
+ build/
21
22
 
data/CHANGELOG.md CHANGED
@@ -3,7 +3,9 @@
3
3
  ## Bug Fixes
4
4
 
5
5
  ## Features
6
- - Added <code>configure</code> to allow changing configuration options after the resource has been initially configured.
6
+ - Added <code>configure</code> function to allow changing configuration options after the resource has been initially configured.
7
+ - Separated out RailsResource into separate service to allow subclassing without using the factories.
8
+ - Added snapshot and rollback extension, be sure to check the [README](README.md#serializers) for details.
7
9
 
8
10
  ## Breaking Changes
9
11
  - <code>railsResourceFactoryProvider</code> settings have been moved to <code>RailsResourceProvider</code>
@@ -13,6 +15,60 @@
13
15
  - <code>enableRootWrapping</code> was renamed <code>rootWrapping</code>
14
16
  - <code>rootName</code> was renamed <code>name</code>
15
17
  - <code>rootPluralName</code> was renamed <code>pluralName</code>
18
+ - Query parameters were not underscored previously. We are now underscoring parameters by default.
19
+ The configuration option <code>underscoreParams</code> can be set to false to disable the renaming.
20
+
21
+ <a name="1.0.0-pre.3"></a>
22
+ # 1.0.0-pre.3
23
+ ## Features
24
+ - Added mixin capability, see [README](README.md#mixins) for details
25
+ - Added snapshot and rollback extension, see [README](README.md#serializers) for details.
26
+ - Added <code>underscoreParams</code> configuration option to allow turning off parameter underscore renaming.
27
+
28
+ ## Breaking Changes
29
+ - Query parameters were not underscored previously. We are now underscoring parameters by default.
30
+ The configuration option <code>underscoreParams</code> can be set to false to disable the renaming.
31
+
32
+ <a name="1.0.0-pre.2"></a>
33
+ # 1.0.0-pre.2
34
+ ## Bug Fixes
35
+ - Support submitting array data (#85)
36
+
37
+ <a name="1.0.0-pre.1"></a>
38
+ # 1.0.0-pre.1
39
+ ## Bug Fixes
40
+
41
+ ## Features
42
+ - Added <code>configure</code> function to allow changing configuration options after the resource has been initially configured.
43
+ - Separated out RailsResource into separate service to allow subclassing without using the factories.
44
+
45
+ ## Breaking Changes
46
+ - <code>railsResourceFactoryProvider</code> settings have been moved to <code>RailsResourceProvider</code>
47
+ - <code>wrapData</code> config option has been renamed <code>rootWrapping</code>
48
+ - All resource settings are now stored under the <code>config</code> property on the resource and should be modified using the <code>configure</code> function.
49
+ - The following resource settings have been renamed:
50
+ - <code>enableRootWrapping</code> was renamed <code>rootWrapping</code>
51
+ - <code>rootName</code> was renamed <code>name</code>
52
+ - <code>rootPluralName</code> was renamed <code>pluralName</code>
53
+ - Query parameters were not underscored previously. We are now underscoring parameters by default.
54
+ The configuration option <code>underscoreParams</code> can be set to false to disable the renaming.
55
+ - Replaced <code>railsRootWrappingTransformer</code> and <code>railsRootWrappingInterceptor</code> with <code>railsRootWrapper</code>
56
+ that has wrap & unwrap methods. This eliminates the need for using promises during resource construction to handle unwrapping
57
+ data passed into the constructor.
58
+ - Resource constructor no longer executes response interceptors. If you need to customize the constructor you should look
59
+ at using subclassing instead.
60
+ - <code>processResponse</code>, <code>transformData</code>, <code>callInterceptors</code> have all been removed as part of rewriting
61
+ the request / response handling.
62
+
63
+ <a name="0.2.5"></a>
64
+ # 0.2.5
65
+ ## Bug Fixes
66
+ - Support submitting array data (#85)
67
+
68
+ <a name="0.2.4"></a>
69
+ # 0.2.4
70
+ ## Bug Fixes
71
+ - Fix mapped name behavior when using serializer default exclusion (#81)
16
72
 
17
73
  <a name="0.2.3"></a>
18
74
  # 0.2.3
data/Gruntfile.js CHANGED
@@ -1,14 +1,17 @@
1
1
  module.exports = function(grunt) {
2
-
3
2
  var path = require('path');
4
3
 
5
4
  var srcFolder = 'vendor/assets/javascripts/angularjs/rails/resource/',
6
5
  srcFiles = ["index.js", "utils/**/*.js", "serialization.js", "resource.js"].map(function(glob) {
7
6
  return srcFolder + glob;
7
+ }),
8
+ extensionFiles = ["extensions/**/*.js"].map(function(glob) {
9
+ return srcFolder + glob;
8
10
  });
9
11
 
10
12
  grunt.initConfig({
11
13
  pkg: grunt.file.readJSON('package.json'),
14
+
12
15
  meta: {
13
16
  banner: '/**\n' +
14
17
  ' * <%= pkg.description %>\n' +
@@ -17,9 +20,21 @@ module.exports = function(grunt) {
17
20
  ' * @author <%= pkg.author %>\n' +
18
21
  ' */\n'
19
22
  },
23
+
20
24
  dirs: {
21
- dest: './'
25
+ dest: 'build'
26
+ },
27
+
28
+ clean: ['<%= dirs.dest %>'],
29
+
30
+ copy: {
31
+ extensions: {
32
+ files: [
33
+ {expand: true, flatten: true, src: extensionFiles, dest: '<%= dirs.dest %>/extensions'}
34
+ ]
35
+ }
22
36
  },
37
+
23
38
  concat: {
24
39
  options: {
25
40
  banner: "<%= meta.banner %>"
@@ -30,25 +45,35 @@ module.exports = function(grunt) {
30
45
  options: {
31
46
  process: function(src, filepath) {
32
47
  return src.replace(/^\/\/= require.*\n/gm, '');
33
- },
34
- },
48
+ }
49
+ }
35
50
  }
36
51
  },
37
- zip: {
38
- '<%= dirs.dest %>/angularjs-rails-resource.zip': ['<%= dirs.dest %>/<%= pkg.name %>.js', '<%= dirs.dest %>/<%= pkg.name %>.min.js']
52
+
53
+ compress: {
54
+ dist: {
55
+ options: {
56
+ archive: '<%= dirs.dest %>/angularjs-rails-resource.zip'
57
+ },
58
+ files: [
59
+ {expand: true, cwd: '<%= dirs.dest %>', src: ['**/*.js']}
60
+ ]
61
+ }
39
62
  },
63
+
40
64
  uglify: {
41
65
  options: {
42
66
  banner: "<%= meta.banner %>"
43
67
  },
44
68
  dist: {
45
- files: {
46
- '<%= dirs.dest %>/<%= pkg.name %>.min.js': ['<%= concat.dist.dest %>']
47
- }
69
+ files: [
70
+ {expand: true, cwd: '<%= dirs.dest %>', src: ['**/*.js'], dest: '<%= dirs.dest %>', ext: '.min.js'}
71
+ ]
48
72
  }
49
73
  },
74
+
50
75
  jshint: {
51
- files: ['gruntfile.js'],
76
+ files: ['gruntfile.js'].concat(srcFiles),
52
77
  options: {
53
78
  // options here to override JSHint defaults
54
79
  globals: {
@@ -56,9 +81,19 @@ module.exports = function(grunt) {
56
81
  }
57
82
  }
58
83
  },
84
+
59
85
  watch: {
60
86
  files: ['<%= jshint.files %>'],
61
- tasks: ['jshint', 'qunit']
87
+ tasks: ['jshint']
88
+ },
89
+
90
+ bump: {
91
+ options: {
92
+ files: ['package.json', 'bower.json'],
93
+ commit: false,
94
+ createTag: false,
95
+ push: false
96
+ }
62
97
  }
63
98
  });
64
99
 
@@ -66,30 +101,10 @@ module.exports = function(grunt) {
66
101
  grunt.loadNpmTasks('grunt-contrib-jshint');
67
102
  grunt.loadNpmTasks('grunt-contrib-watch');
68
103
  grunt.loadNpmTasks('grunt-contrib-concat');
69
- grunt.loadNpmTasks('grunt-zip');
70
-
71
- grunt.registerTask('default', ['jshint', 'concat', 'uglify', 'zip']);
72
-
73
- // Provides the "bump" task.
74
- grunt.registerTask('bump', 'Increment version number', function() {
75
- var versionType = grunt.option('type');
76
- function bumpVersion(version, versionType) {
77
- var type = {patch: 2, minor: 1, major: 0},
78
- parts = version.split('.'),
79
- idx = type[versionType || 'patch'];
80
- parts[idx] = parseInt(parts[idx], 10) + 1;
81
- while(++idx < parts.length) { parts[idx] = 0; }
82
- return parts.join('.');
83
- }
84
- var version;
85
- function updateFile(file) {
86
- var json = grunt.file.readJSON(file);
87
- version = json.version = bumpVersion(json.version, versionType || 'patch');
88
- grunt.file.write(file, JSON.stringify(json, null, ' '));
89
- }
90
- updateFile('package.json');
91
- updateFile('bower.json');
92
- grunt.log.ok('Version bumped to ' + version);
93
- });
104
+ grunt.loadNpmTasks('grunt-contrib-copy');
105
+ grunt.loadNpmTasks('grunt-contrib-clean');
106
+ grunt.loadNpmTasks('grunt-contrib-compress');
107
+ grunt.loadNpmTasks('grunt-bump');
94
108
 
109
+ grunt.registerTask('default', ['jshint', 'clean', 'concat', 'copy', 'uglify', 'compress']);
95
110
  };
data/README.md CHANGED
@@ -26,18 +26,13 @@ Book.query({title: 'Moby Dick'}).then(function (books) {
26
26
  You can inject the <code>railsSerializerProvider</code> into your application config function and override the <code>underscore</code>
27
27
  and <code>camelize</code> functions:
28
28
  ````javascript
29
- angular.module('app').config(function (railsSerializerFactory) {
30
- railsSerializerProvider.
31
- underscore(function (name) {
32
- return name;
33
- }).
34
- camelize(function (name) {
35
- return name;
36
- });
37
- });
29
+ angular.module('app').config(["railsSerializerProvider", function(railsSerializerProvider) {
30
+ railsSerializerProvider.underscore(angular.identity).camelize(angular.identity);
31
+ }]);
38
32
  ````
39
33
 
40
34
  ## Installation
35
+ ### Rails Asset Pipeline
41
36
  Add this line to your application's Gemfile to use the latest stable version:
42
37
  ```ruby
43
38
  gem 'angularjs-rails-resource', '~> 0.2.3'
@@ -47,6 +42,19 @@ Include the javascript somewhere in your asset pipeline:
47
42
  ```javascript
48
43
  //= require angularjs/rails/resource
49
44
  ```
45
+
46
+ To add extensions just add additional requires:
47
+ ```javascript
48
+ //= require angularjs/rails/resource/extensions/snapshots
49
+ ```
50
+
51
+ ### Standalone
52
+ If you aren't using the Rails asset pipeline you can download the combined
53
+ [angularjs-rails-resource.js](https://github.com/FineLinePrototyping/dist-angularjs-rails-resource/blob/master/angularjs-rails-resource.js)
54
+ or [angularjs-rails-resource.min.js](https://github.com/FineLinePrototyping/dist-angularjs-rails-resource/blob/master/angularjs-rails-resource.min.js).
55
+
56
+ You can also use [Bower](http://bower.io/) to install <code>angularjs-rails-resource</code>.
57
+
50
58
  ## Branching and Versioning
51
59
  As much as possible we will try to adhere to the [SemVer](http://semver.org/) guidelines on release numbering.
52
60
 
@@ -57,35 +65,71 @@ Release branches should remain stable but it is always best to rely on the ruby
57
65
  ## Changes
58
66
  Make sure to check the [CHANGELOG](CHANGELOG.md) for any breaking changes between releases.
59
67
 
60
- ## Dependencies
61
- Since this is an [AngularJS](http://angularjs.org) module it of course depends on that but more specifically the it depends on the following AngularJS services:
62
-
63
- * [$http](http://docs.angularjs.org/api/ng.$http)
64
- * [$q](http://docs.angularjs.org/api/ng.$q)
65
- * [$injector](http://docs.angularjs.org/api/AUTO.$injector)
66
- * [$interpolate](http://docs.angularjs.org/api/ng.$interpolate)
67
-
68
68
  ## Usage
69
- There are a lot of different ways that you can use the resources and we try not to force you into any specific pattern
69
+ There are a lot of different ways that you can use the resources and we try not to force you into any specific pattern.
70
+ All of the functionality is packed in an AngularJS module named "rails" so make sure that your modules depend on that module
71
+ for the dependency injection to work properly.
70
72
 
71
73
  There are more examples available in [EXAMPLES.md](EXAMPLES.md).
72
74
 
75
+ ### Defining Resources
76
+ There are multiple ways that you can set up define new resources in your application.
77
+
78
+ #### railsResourceFactory
79
+ Similar to $resource, we provide a <code>railsResourceFactory(config)</code> function that takes a config object with the configuration
80
+ settings for the new resource. The factory function returns a new class that is extended from RailsResource.
73
81
 
74
- ### Basic Example
75
- In order to create a Book resource, we would first define the factory within a module.
76
82
  ```javascript
77
83
  angular.module('book.services', ['rails']);
78
84
  angular.module('book.services').factory('Book', ['railsResourceFactory', function (railsResourceFactory) {
79
- return railsResourceFactory({url: '/books', name: 'book'});
85
+ return railsResourceFactory({
86
+ url: '/books',
87
+ name: 'book'
88
+ });
80
89
  }]);
81
90
  ```
82
- We would then inject that service into a controller:
91
+
92
+ #### RailsResource extension
93
+ We also expose the RailsResource as base class that you can extend to create your own resource classes. Extending the RailsResource class
94
+ directly gives you a bit more flexibility to add custom constructor code. There are probably ten different ways to extend the class but
95
+ the two that we intend to be used are through CoffeeScript or through the same logic that the factory function uses.
96
+
97
+ ##### CoffeeScript
98
+ To allow better integration with CoffeeScript, we expose the RailsResource as a base class that can be extended to create
99
+ resource classes. When extending RailsResource you should use the <code>@configure</code> function to set configuration
100
+ properties for the resource. You can call <code>@configure</code> multiple times to set additional properties as well.
101
+
102
+ ````coffeescript
103
+ class Book extends RailsResource
104
+ @configure url: '/books', name: 'book'
105
+
106
+ class Encyclopedia extends Book
107
+ @configure url: '/encyclopedias', name: 'encyclopedia'
108
+ ````
109
+
110
+ ##### JavaScript
111
+ Since the purpose of exposing the RailsResource was to allow for CoffeeScript users to create classes from it the JavaScript way
112
+ is basically just the same as the generated CoffeeScript code. The <code>RailsResource.extendTo</code> function is a modification
113
+ of the <code>__extends</code> function that CoffeeScript generates.
114
+
115
+ ````javascript
116
+ function Resource() {
117
+ Resource.__super__.constructor.apply(this, arguments);
118
+ }
119
+
120
+ RailsResource.extendTo(Resource);
121
+ Resource.configure(config);
122
+ ````
123
+
124
+ ### Using Resources
83
125
  ```javascript
84
126
  angular.module('book.controllers').controller('BookShelfCtrl', ['$scope', 'Book', function ($scope, Book) {
85
127
  $scope.searching = true;
86
128
  // Find all books matching the title
87
- $scope.books = Book.query({title: title});
88
- $scope.books.then(function(results) {
129
+ $scope.books = Book.query({
130
+ title: title
131
+ });
132
+ $scope.books.then(function (results) {
89
133
  $scope.searching = false;
90
134
  }, function (error) {
91
135
  $scope.searching = false;
@@ -98,12 +142,17 @@ angular.module('book.controllers').controller('BookShelfCtrl', ['$scope', 'Book'
98
142
  });
99
143
 
100
144
  // Create a book and save it
101
- new Book({title: 'Gardens of the Moon', author: 'Steven Erikson', isbn: '0-553-81957-7'}).create();
145
+ new Book({
146
+ title: 'Gardens of the Moon',
147
+ author: 'Steven Erikson',
148
+ isbn: '0-553-81957-7'
149
+ }).create();
102
150
  }]);
103
151
  ```
104
152
 
105
- ### Serializer
106
- When defining a resource, you can pass a custom [serializer](#serializers) using the <code>serializer</code> configuration option.
153
+ ### Custom Serialization
154
+ When defining a resource, you can pass a custom [serializer](#serializers) using the <code>serializer</code> configuration option to
155
+ alter the behavior of the object serialization.
107
156
  ```javascript
108
157
  Author = railsResourceFactory({
109
158
  url: '/authors',
@@ -117,7 +166,7 @@ Author = railsResourceFactory({
117
166
  ```
118
167
  You can also specify a serializer as a factory and inject it as a dependency.
119
168
  ```javascript
120
- angular.module('rails').factory('BookSerializer', function(railsSerializer) {
169
+ angular.module('rails').factory('BookSerializer', function (railsSerializer) {
121
170
  return railsSerializer(function () {
122
171
  this.exclude('publicationDate', 'relatedBooks');
123
172
  this.rename('ISBN', 'isbn');
@@ -134,47 +183,14 @@ Book = railsResourceFactory({
134
183
  name: 'book',
135
184
  serializer: 'BookSerializer'
136
185
  });
137
-
138
186
  ```
139
- ## Resource Creation
140
- There are multiple ways that you can set up new resources in your application.
141
-
142
- ### railsResourceFactory
143
- Similar to $resource, we provide a <code>railsResourceFactory(config)</code> function that takes a config object with the configuration
144
- settings for the new resource. The factory function returns a new class that is extended from RailsResource.
145
-
146
- ### RailsResource extension
147
- We also expose the RailsResource as base class that you can extend to create your own resource classes. Extending the RailsResource class
148
- directly gives you a bit more flexibility to add custom constructor code. There are probably ten different ways to extend the class but
149
- the two that we intend to be used are through CoffeeScript or through the same logic that the factory function uses.
150
-
151
- #### CoffeeScript
152
- ````coffeescript
153
- class Book extends RailsResource
154
- @configure url: '/books', name: 'book'
155
187
 
156
- class Encyclopedia extends Book
157
- @configure url: '/encyclopedias', name: 'encyclopedia'
158
- ````
159
-
160
- #### JavaScript
161
- Since the purpose of exposing the RailsResource was to allow for CoffeeScript users to create classes from it the JavaScript way
162
- is basically just the same as the generated CoffeeScript code. The <code>RailsResource.extend</code> function is a modification
163
- of the <code>__extends</code> function that CoffeeScript generates.
164
-
165
- ````javascript
166
- function Resource() {
167
- Resource.__super__.constructor.apply(this, arguments);
168
- }
169
-
170
- RailsResource.extend(Resource);
171
- Resource.configure(config);
172
- ````
173
188
 
174
189
  ### Config Options
175
190
 
176
191
  The following configuration options are available for customizing resources. Each of the configuration options can be passed as part of an object
177
- to the <code>railsResourceFactory</code> function or to the resource's <code>configure</code> function.
192
+ to the <code>railsResourceFactory</code> function or to the resource's <code>configure</code> function. The <code>configure</code> function
193
+ defined on the resource can be called multiple times to adjust properties as needed.
178
194
 
179
195
  * **url** - This is the url of the service. See [Resource URLs](#resource-urls) below for more information.
180
196
  * **rootWrapping** - (Default: true) Turns on/off root wrapping on JSON (de)serialization.
@@ -186,8 +202,9 @@ to the <code>railsResourceFactory</code> function or to the resource's <code>con
186
202
  * **Accept** - application/json
187
203
  * **Content-Type** - application/json
188
204
  * **defaultParams** *(optional)* - If the resource expects a default set of query params on every call you can specify them here.
205
+ * **underscoreParams** *(optional)* - Controls whether or not query parameters are converted from camel case to underscore.
189
206
  * **updateMethod** *(optional)* - Allows overriding the default HTTP method (PUT) used for update. Valid values are "post", "put", or "patch".
190
- * **serializer** *(optional)* - Allows specifying a custom [serializer](#serializers) allow configuring custom serialization options.
207
+ * **serializer** *(optional)* - Allows specifying a custom [serializer](#serializers) to configure custom serialization options.
191
208
  * **requestTransformers** *(optional) - See [Transformers / Interceptors](#transformers--interceptors)
192
209
  * **responseInterceptors** *(optional)* - See [Transformers / Interceptors](#transformers--interceptors)
193
210
  * **afterResponseInterceptors** *(optional)* - See [Transformers / Interceptors](#transformers--interceptors)
@@ -200,10 +217,11 @@ For example, you should specify "publishingCompany" and "publishingCompanies" in
200
217
  The individual resource configuration takes precedence over application-wide default configuration values.
201
218
  Each 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.
202
219
 
203
- * rootWrapping - {function(boolean):railsSerializerProvider}
204
- * httpConfig - {function(object):railsSerializerProvider}
205
- * defaultParams - {function(object):railsSerializerProvider}
206
- * updateMethod - {function(boolean):railsSerializerProvider}
220
+ * rootWrapping - {function(boolean):RailsResourceProvider}
221
+ * httpConfig - {function(object):RailsResourceProvider}
222
+ * defaultParams - {function(object):RailsResourceProvider}
223
+ * underscoreParams - {function(boolean):RailsResourceProvider}
224
+ * updateMethod - {function(boolean):RailsResourceProvider}
207
225
 
208
226
  For example, to turn off the root wrapping application-wide and set the update method to PATCH:
209
227
 
@@ -247,6 +265,10 @@ RailsResources have the following class methods available.
247
265
 
248
266
  * configure(options) - Change one or more configuration option for a resource.
249
267
 
268
+ * 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
269
+
270
+ * include(...module) - Includes a mixin module into the resource. See [Mixins](#mixins) for more information
271
+
250
272
  * setUrl(url) - Updates the url for the resource, same as calling <code>configure({url: url})</code>
251
273
 
252
274
  * $url(context, path) - Returns the resource URL using the given context with the optional path appended if provided.
@@ -441,6 +463,119 @@ The resource also exposes a class method <code>afterResponse(fn)</code> that acc
441
463
  to 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
442
464
  as an interceptor.
443
465
 
466
+ ## Mixins
467
+ The ability to add a [Mixin](http://en.wikipedia.org/wiki/Mixin) to a RailsResource is modeled after the example code in
468
+ in 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).
469
+
470
+ RailsResource provides two methods:
471
+ * **extend** - Add class properties / methods to the resource
472
+ * **include** - Add instance properties / methods to the resource prototype chain
473
+
474
+ When you call <code>extend</code> or <code>include</code> the mixin will be added to the resource. If your mixin provides
475
+ one of the callback methods (<code>extended</code> or <code>included</code>) then those methods will be called when the mixin
476
+ is added. One additional change from the normal mixin behavior is that your mixins can implement an additional <code>configure</code>
477
+ function that will be called whenever the resource's <code>configure</code> function is called. That way the mixin can provide
478
+ additional configuration options.
479
+
480
+ ## Extensions
481
+ Extensions are provided [mixins](#mixins) that follow specific naming pattern to make it easier to include them by a shortened name.
482
+
483
+ The available extension names are:
484
+ * [snapshots](#snapshots) - RailsResourceSnapshotsMixin
485
+
486
+ To include an extension, you have to first include the extension in your project.
487
+ You then need to add the extension to the in one of the following ways to RailsResource:
488
+
489
+ ### Application-wide Resource Extensions
490
+ <code>RailsResourceProvider.extensions</code> - adds the extension to all RailsResources within the application.
491
+ ````javascript
492
+ app.config(function (RailsResourceProvider) {
493
+ RailsResourceProvider.extensions('snapshots');
494
+ });
495
+ ````
496
+
497
+ ### Per-Resource Extensions
498
+ #### Configuration Option
499
+ The <code>extensions</code> configuration option adds the extension to a single RailsResource
500
+
501
+ ##### JavaScript
502
+ ````javascript
503
+ Book = railsResourceFactory({
504
+ url: '/books',
505
+ name: 'book',
506
+ extensions: ['snapshots']
507
+ });
508
+ ````
509
+ ##### CoffeeScript
510
+ ````coffeescript
511
+ class Book extends RailsResource
512
+ @configure url: '/books', name: 'book', extensions: ['snapshots']
513
+ ````
514
+
515
+ #### RailsResource.extend
516
+ RailsResource.extend - explicitly include the extension as a module
517
+
518
+ ##### JavaScript
519
+ ````javascript
520
+ Book = railsResourceFactory({ url: '/books', name: 'book' });
521
+ // by name
522
+ Book.extend('RailsResourceSnapshotsMixin');
523
+ // or by injected reference
524
+ Book.extend(RailsResourceSnapshotsMixin);
525
+ ````
526
+
527
+ ##### CoffeeScript
528
+
529
+ ````coffeescript
530
+ class Book extends RailsResource
531
+ @configure url: '/books', name: 'book'
532
+ @extend 'RailsResourceSnapshotsMixin'
533
+ ````
534
+
535
+ ### Snapshots
536
+ Snapshots 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
537
+ saved snapshots and yes, you can create as many snapshots as you want.
538
+
539
+ Snapshots serialize the resource instance and save off a copy of the serialized data in the <code>$snapshots</code> array on the instance.
540
+ If 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
541
+ different serialization options. If so, you can specify an specific serializer for snapshots using the <code>snapshotSerializer</code> configuration
542
+ option.
543
+
544
+ Calling <code>save</code>, <code>create</code>, <code>update</code>, or <code>delete</code>/<code>remove</code> on a resource instance
545
+ will remove all snapshots when the operation completes successfully.
546
+
547
+ #### Configuration Options
548
+ * **snapshotSerializer** *(optional)* - Allows specifying a custom [serializer](#serializers) to configure custom serialization options specific to [snapshot and rollback](#snapshots).
549
+
550
+
551
+ #### Creating Snapshots
552
+ Creating a snapshot is easy, just call the <code>snapshot</code> function. You can pass an optional callback function to <code>snapshot</code> to perform
553
+ additional custom operations after the rollback is complete. The callback function is specific to each snapshot version created so make sure you pass it every
554
+ time if it's a callback you always want called.
555
+
556
+ #### Rolling back
557
+ So 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>
558
+ and <code>rollbackTo</code>. Each method will:
559
+ * Deserialize the snapshot data and update the resource instance with the new data.
560
+ * Remove all snapshots newer than the version being rolled back to.
561
+ * Call the rollback callback if it was specified on the <code>snapshot</code> in the context of the resource instance.
562
+
563
+ ##### rollback
564
+ <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
565
+ snapshot version. <code>numVersions</code> can be used to roll back further than the last snapshot version based on the following rules:
566
+
567
+ * When <code>numVersions</code> is undefined or 0 then a single version is rolled back.
568
+ * When <code>numVersions</code> exceeds the stored number of snapshots then the resource is rolled back to the first snapshot version.
569
+ * When <code>numVersions</code> is less than 0 then the resource is rolled back to the first snapshot version.
570
+ * Otherwise, <code>numVersions</code> represents the nth version from the last snapshot version (similar to calling rollback <code>numVersions</code> times).
571
+
572
+ ##### rollbackTo
573
+ <code>rollbackTo(snapshotVersion)</code> allows you to roll back the resource to a specific snapshot version.
574
+
575
+ * When <code>snapshotVersion</code> is greater than the number of versions then the last snapshot version will be used.
576
+ * When <code>snapshotVersion</code> is less than 0 then the resource will be rolled back to the first version.
577
+ * Otherwise, the resource will be rolled back to the specific version specified.
578
+
444
579
  ## Tests
445
580
  The tests are written using [Jasmine](http://pivotal.github.com/jasmine/) and are run using [Karma](https://github.com/karma-runner/karma).
446
581