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

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 6949c58b7d5354dcb4b311248088c8f831c958c6
4
- data.tar.gz: da054ff28d6285541d7f0e5a1deb23b3b83fb91c
3
+ metadata.gz: e088a0ef4c31ca6952015c7e5bf25e29a3aeffa6
4
+ data.tar.gz: ceafd0fc62d19853922b36a79b3926cd1ca579c9
5
5
  SHA512:
6
- metadata.gz: 8e2c661c2fcd2df398eeeb071c607f39e258f53e28bd5e9c9670616182a7a984ecb786ba91b2a680fc71299479f6e3a97e6449a6a8bd759743c59e36452bdee3
7
- data.tar.gz: f63c1513e65a2254390bc3205eaeb0541b2f35f6c24669f8d52b140f2a4ff9f5fc8ea9b6bd641781d5f66fdc9ba1e09497adc73148163b7f056766136c32f69b
6
+ metadata.gz: 8715afd2c22e4a5341512ba1845d83c6b5044cb6592dec4574fe530f908866ad9a48cc9f51b1fcfefe977bd30cf8661e5e39f2240c61ed9a0237be1cb81a6e28
7
+ data.tar.gz: 93efebbbb2920fe2f2d6deb883bdfbe18cb8e5a720e93c946471deb1b9e8d6794820421e1dd4589179fc9643fb2c0eed90261458dbea030f05b291deda8f894c
data/EXAMPLES.md CHANGED
@@ -7,74 +7,74 @@ For example, suppose we have an Author that serializes all of the books that aut
7
7
  are a nested resource that allows us to more easily perform updates against those books without having to worry about creating
8
8
  a resource instance for the book.
9
9
 
10
- angular.module('book.services', ['rails']);
11
-
12
- angular.module('book.services').factory('Book', ['railsResourceFactory', function (railsResourceFactory) {
13
- return railsResourceFactory({url: '/books', name: 'book'});
14
- }]);
15
-
16
- angular.module('book.services').factory('Author', ['railsResourceFactory', 'railsSerializer', function (railsResourceFactory, railsSerializer) {
17
- return railsResourceFactory({
18
- url: '/authors',
19
- name: 'author',
20
- serializer: railsSerializer(function () {
21
- this.resource('books', 'Book');
22
- });
23
- });
24
- }]);
25
-
26
- angular.module('book.controllers').controller('AuthorCtrl', ['$scope', 'Author', function ($scope, Author) {
27
- $scope.author = Author.get(123);
28
-
29
- // allow the view to trigger an update to a book from $scope.author.books
30
- $scope.updateBook = function (book) {
31
- book.update();
32
- }
33
- }]);
10
+ angular.module('book.services', ['rails']);
11
+
12
+ angular.module('book.services').factory('Book', ['railsResourceFactory', function (railsResourceFactory) {
13
+ return railsResourceFactory({url: '/books', name: 'book'});
14
+ }]);
15
+
16
+ angular.module('book.services').factory('Author', ['railsResourceFactory', 'railsSerializer', function (railsResourceFactory, railsSerializer) {
17
+ return railsResourceFactory({
18
+ url: '/authors',
19
+ name: 'author',
20
+ serializer: railsSerializer(function () {
21
+ this.resource('books', 'Book');
22
+ })
23
+ });
24
+ }]);
25
+
26
+ angular.module('book.controllers').controller('AuthorCtrl', ['$scope', 'Author', function ($scope, Author) {
27
+ $scope.author = Author.get(123);
28
+
29
+ // allow the view to trigger an update to a book from $scope.author.books
30
+ $scope.updateBook = function (book) {
31
+ book.update();
32
+ }
33
+ }]);
34
34
 
35
35
  # Nested attributes
36
36
  While we don't have logic for full nested attributes support, the new serializer does allow you to specify which fields
37
37
  should be passed with the <code>_attributes</code> suffix.
38
38
 
39
- angular.module('book.services').factory('Book', ['railsResourceFactory', 'railsSerializer', function (railsResourceFactory, railsSerializer) {
40
- return railsResourceFactory({
41
- url: '/books',
42
- name: 'book',
43
- serializer: railsSerializer(function () {
44
- this.nestedAttribute('author');
45
- });
46
- });
47
- }]);
39
+ angular.module('book.services').factory('Book', ['railsResourceFactory', 'railsSerializer', function (railsResourceFactory, railsSerializer) {
40
+ return railsResourceFactory({
41
+ url: '/books',
42
+ name: 'book',
43
+ serializer: railsSerializer(function () {
44
+ this.nestedAttribute('author');
45
+ })
46
+ });
47
+ }]);
48
48
 
49
49
  # Excluding attributes from serialization
50
50
  Sometimes you don't want to serialize certain fields when updating an object. Take for instance the case of the author on a book.
51
51
  We know that we don't accept nested attributes for the author on the server so we want to exclude it from the JSON to reduce
52
52
  the amount of data being sent to the server.
53
53
 
54
- angular.module('book.services').factory('Book', ['railsResourceFactory', 'railsSerializer', function (railsResourceFactory railsSerializer) {
55
- return railsResourceFactory({
56
- url: '/books',
57
- name: 'book',
58
- serializer: railsSerializer(function () {
59
- this.exclude('author');
60
- });
61
- });
62
- }]);
54
+ angular.module('book.services').factory('Book', ['railsResourceFactory', 'railsSerializer', function (railsResourceFactory railsSerializer) {
55
+ return railsResourceFactory({
56
+ url: '/books',
57
+ name: 'book',
58
+ serializer: railsSerializer(function () {
59
+ this.exclude('author');
60
+ })
61
+ });
62
+ }]);
63
63
 
64
64
 
65
65
  # Only allowing specific attributes for serialization
66
66
  You can also be very restrictive and only include specific attributes that you want to send to the server. All other attribtues
67
67
  would be excluded by default.
68
68
 
69
- angular.module('book.services').factory('Book', ['railsResourceFactory', 'railsSerializer', function (railsResourceFactory. railsSerializer) {
70
- return railsResourceFactory({
71
- url: '/books',
72
- name: 'book',
73
- serializer: railsSerializer(function () {
74
- this.only('id', 'isbn', 'publicationDate');
75
- });
76
- });
77
- }]);
69
+ angular.module('book.services').factory('Book', ['railsResourceFactory', 'railsSerializer', function (railsResourceFactory. railsSerializer) {
70
+ return railsResourceFactory({
71
+ url: '/books',
72
+ name: 'book',
73
+ serializer: railsSerializer(function () {
74
+ this.only('id', 'isbn', 'publicationDate');
75
+ })
76
+ });
77
+ }]);
78
78
 
79
79
 
80
80
  # Adding custom methods to a resource
@@ -84,61 +84,61 @@ You can add additional "class" or "instance" methods by modifying the resource r
84
84
  For instance, if you wanted to add a method that would search for Books by the title without having to construct the query params
85
85
  each time you could add a new <code>findByTitle</code> class function.
86
86
 
87
- angular.module('book.services', ['rails']);
88
- angular.module('book.services').factory('Book', ['railsResourceFactory', function (railsResourceFactory) {
89
- var resource = railsResourceFactory({url: '/books', name: 'book'});
90
- resource.findByTitle = function (title) {
91
- return resource.query({title: title});
92
- };
93
- return resource;
94
- }]);
95
-
96
- angular.module('book.controllers').controller('BookShelfCtrl', ['$scope', 'Book', function ($scope, Book) {
97
- $scope.searching = true;
98
- // Find all books matching the title
99
- $scope.books = Book.findByTitle({title: title});
100
- $scope.books.then(function(results) {
101
- $scope.searching = false;
102
- }, function (error) {
103
- $scope.searching = false;
104
- });
105
- }]);
87
+ angular.module('book.services', ['rails']);
88
+ angular.module('book.services').factory('Book', ['railsResourceFactory', function (railsResourceFactory) {
89
+ var resource = railsResourceFactory({url: '/books', name: 'book'});
90
+ resource.findByTitle = function (title) {
91
+ return resource.query({title: title});
92
+ };
93
+ return resource;
94
+ }]);
95
+
96
+ angular.module('book.controllers').controller('BookShelfCtrl', ['$scope', 'Book', function ($scope, Book) {
97
+ $scope.searching = true;
98
+ // Find all books matching the title
99
+ $scope.books = Book.findByTitle({title: title});
100
+ $scope.books.then(function(results) {
101
+ $scope.searching = false;
102
+ }, function (error) {
103
+ $scope.searching = false;
104
+ });
105
+ }]);
106
106
 
107
107
  ## Get related object
108
108
  You can also add additional methods on the object prototype chain so all instances of the resource have that function available.
109
109
  The following example exposes a <code>getAuthor</code> instance method that would be accessible on all Book instances.
110
110
 
111
- angular.module('book.services', ['rails']);
112
- angular.module('book.services').factory('Author', ['railsResourceFactory', function (railsResourceFactory) {
113
- return railsResourceFactory({url: '/authors', name: 'author'});
114
- }]);
115
- angular.module('book.services').factory('Book', ['railsResourceFactory', 'Author', function (railsResourceFactory, Author) {
116
- var resource = railsResourceFactory({url: '/books', name: 'book'});
117
- resource.prototype.getAuthor = function () {
118
- return Author.get(this.authorId);
119
- };
120
- }]);
121
- angular.module('book.controllers').controller('BookShelfCtrl', ['$scope', 'Book', function ($scope, Book) {
122
- $scope.getAuthorDetails = function (book) {
123
- $scope.author = book.getAuthor();
124
- };
125
- }]);
111
+ angular.module('book.services', ['rails']);
112
+ angular.module('book.services').factory('Author', ['railsResourceFactory', function (railsResourceFactory) {
113
+ return railsResourceFactory({url: '/authors', name: 'author'});
114
+ }]);
115
+ angular.module('book.services').factory('Book', ['railsResourceFactory', 'Author', function (railsResourceFactory, Author) {
116
+ var resource = railsResourceFactory({url: '/books', name: 'book'});
117
+ resource.prototype.getAuthor = function () {
118
+ return Author.get(this.authorId);
119
+ };
120
+ }]);
121
+ angular.module('book.controllers').controller('BookShelfCtrl', ['$scope', 'Book', function ($scope, Book) {
122
+ $scope.getAuthorDetails = function (book) {
123
+ $scope.author = book.getAuthor();
124
+ };
125
+ }]);
126
126
 
127
127
  ## Nested URL
128
128
  Or say you instead had a nested "references" service call that returned a list of referenced books for a given book instance. In that case you can add your own addition method that calls $http.get and then
129
129
  passes the resulting promise to the processResponse method which will perform the same transformations and handling that the get or query would use.
130
130
 
131
- angular.module('book.services', ['rails']);
132
- angular.module('book.services').factory('Book', ['railsResourceFactory', '$http', function (railsResourceFactory, $http) {
133
- var resource = railsResourceFactory({url: '/books', name: 'book'});
134
- resource.prototype.getReferences = function () {
135
- var self = this;
136
- return resource.$get(self.$url('references'))).then(function (references) {
137
- self.references = references;
138
- return self.references;
139
- });
140
- };
141
- }]);
131
+ angular.module('book.services', ['rails']);
132
+ angular.module('book.services').factory('Book', ['railsResourceFactory', '$http', function (railsResourceFactory, $http) {
133
+ var resource = railsResourceFactory({url: '/books', name: 'book'});
134
+ resource.prototype.getReferences = function () {
135
+ var self = this;
136
+ return resource.$get(self.$url('references'))).then(function (references) {
137
+ self.references = references;
138
+ return self.references;
139
+ });
140
+ };
141
+ }]);
142
142
 
143
143
  # Specifying Transformer
144
144
  Transformers can be specified by an array of transformers in the configuration options passed to railsResourceFactory.
@@ -147,25 +147,25 @@ a function returned by a factory if you want to share a transformer across multi
147
147
 
148
148
  Both of these examples can be accomplished using the serializers now.
149
149
 
150
- angular.module('test').factory('excludePrivateKeysTransformer', function () {
151
- return function (data) {
152
- angular.forEach(data, function (value, key) {
153
- if (key[0] === '_') {
154
- delete data[key];
155
- }
156
- });
157
- });
158
- });
159
-
160
- angular.module('test').factory('Book', function (railsResourceFactory, excludePrivateKeysTransformer) {
161
- var Book = railsResourceFactory({url: '/books', name: 'book'});
162
- Book.beforeRequest(excludePrivateKeysTransformer);
163
- Book.beforeRequest(function (data) {
164
- data['release_date'] = data['publicationDate'];
165
- delete data['publicationDate'];
166
- });
167
-
168
- return Book;
169
- });
150
+ angular.module('test').factory('excludePrivateKeysTransformer', function () {
151
+ return function (data) {
152
+ angular.forEach(data, function (value, key) {
153
+ if (key[0] === '_') {
154
+ delete data[key];
155
+ }
156
+ });
157
+ });
158
+ });
159
+
160
+ angular.module('test').factory('Book', function (railsResourceFactory, excludePrivateKeysTransformer) {
161
+ var Book = railsResourceFactory({url: '/books', name: 'book'});
162
+ Book.beforeRequest(excludePrivateKeysTransformer);
163
+ Book.beforeRequest(function (data) {
164
+ data['release_date'] = data['publicationDate'];
165
+ delete data['publicationDate'];
166
+ });
167
+
168
+ return Book;
169
+ });
170
170
 
171
171
 
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * A resource factory inspired by $resource from AngularJS
3
- * @version v1.0.0-pre1 - 2013-10-06
3
+ * @version v1.0.0-pre.2 - 2013-11-24
4
4
  * @link https://github.com/FineLinePrototyping/angularjs-rails-resource.git
5
5
  * @author
6
6
  */
@@ -408,8 +408,17 @@
408
408
  Serializer.prototype.getSerializedAttributeName = function (attributeName) {
409
409
  var mappedName = this.serializeMappings[attributeName] || attributeName;
410
410
 
411
- if (this.isExcludedFromSerialization(attributeName) || this.isExcludedFromSerialization(mappedName)) {
412
- return undefined;
411
+ var mappedNameExcluded = this.isExcludedFromSerialization(mappedName),
412
+ attributeNameExcluded = this.isExcludedFromSerialization(attributeName);
413
+
414
+ if(this.options.excludeByDefault) {
415
+ if(mappedNameExcluded && attributeNameExcluded) {
416
+ return undefined;
417
+ }
418
+ } else {
419
+ if (mappedNameExcluded || attributeNameExcluded) {
420
+ return undefined;
421
+ }
413
422
  }
414
423
 
415
424
  return this.underscore(mappedName);
@@ -474,7 +483,7 @@
474
483
 
475
484
  // custom serializer takes precedence over resource serializer
476
485
  if (serializer) {
477
- return RailsResourceInjector.createService(serializer)
486
+ return RailsResourceInjector.createService(serializer);
478
487
  } else if (resource) {
479
488
  return resource.config.serializer;
480
489
  }
@@ -825,7 +834,11 @@
825
834
  }
826
835
 
827
836
  this.config.name = this.config.serializer.underscore(cfg.name);
828
- this.config.pluralName = this.config.serializer.underscore(cfg.pluralName || this.config.serializer.pluralize(this.config.name));
837
+
838
+ // we don't want to turn undefined name into "undefineds" then the plural name won't update when the name is set
839
+ if (this.config.name) {
840
+ this.config.pluralName = this.config.serializer.underscore(cfg.pluralName || this.config.serializer.pluralize(this.config.name));
841
+ }
829
842
 
830
843
  this.config.urlBuilder = railsUrlBuilder(this.config.url);
831
844
  this.config.resourceConstructor = this;
@@ -1036,7 +1049,7 @@
1036
1049
  RailsResource['$' + method] = function (url, data) {
1037
1050
  var config;
1038
1051
  // clone so we can manipulate w/o modifying the actual instance
1039
- data = this.transformData(angular.copy(data, {}));
1052
+ data = this.transformData(angular.copy(data));
1040
1053
  config = angular.extend({method: method, url: url, data: data}, this.getHttpConfig());
1041
1054
  return this.processResponse($http(config));
1042
1055
  };
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * A resource factory inspired by $resource from AngularJS
3
- * @version v1.0.0-pre1 - 2013-10-06
3
+ * @version v1.0.0-pre.2 - 2013-11-24
4
4
  * @link https://github.com/FineLinePrototyping/angularjs-rails-resource.git
5
5
  * @author
6
6
  */
7
- !function(){angular.module("rails",["ng"])}(),function(){angular.module("rails").factory("RailsInflector",function(){function a(a){return angular.isString(a)?a.replace(/_[\w\d]/g,function(a,b,c){return 0===b?a:c.charAt(b+1).toUpperCase()}):a}function b(a){return angular.isString(a)?a.replace(/[A-Z]/g,function(a,b){return 0===b?a:"_"+a.toLowerCase()}):a}function c(a){return a+"s"}return{camelize:a,underscore:b,pluralize:c}})}(),function(a){angular.module("rails").factory("RailsResourceInjector",["$injector",function(b){function c(c){return c?angular.isString(c)?b.get(c):c:a}function d(d){return d?b.instantiate(c(d)):a}return{createService:d,getDependency:c}}])}(),function(){angular.module("rails").factory("railsUrlBuilder",["$interpolate",function(a){return function(b){var c;return angular.isFunction(b)||angular.isUndefined(b)?b:(-1===b.indexOf(a.startSymbol())&&(b=b+"/"+a.startSymbol()+"id"+a.endSymbol()),c=a(b),function(a){return b=c(a),"/"===b.charAt(b.length-1)&&(b=b.substr(0,b.length-1)),b})}}])}(),function(a){angular.module("rails").provider("railsSerializer",function(){var b={underscore:a,camelize:a,pluralize:a,exclusionMatchers:[]};this.underscore=function(a){return b.underscore=a,this},this.camelize=function(a){return b.camelize=a,this},this.pluralize=function(a){return b.pluralize=a,this},this.exclusionMatchers=function(a){return b.exclusionMatchers=a,this},this.$get=["$injector","RailsInflector","RailsResourceInjector",function(c,d,e){function f(c,d){function f(){angular.isFunction(c)&&(d=c,c={}),this.exclusions={},this.inclusions={},this.serializeMappings={},this.deserializeMappings={},this.customSerializedAttributes={},this.preservedAttributes={},this.customSerializers={},this.nestedResources={},this.options=angular.extend({excludeByDefault:!1},b,c||{}),d&&d.call(this,this)}return f.prototype.exclude=function(){var a=this.exclusions;return angular.forEach(arguments,function(b){a[b]=!1}),this},f.prototype.only=function(){var a=this.inclusions;return this.options.excludeByDefault=!0,angular.forEach(arguments,function(b){a[b]=!0}),this},f.prototype.nestedAttribute=function(){var a=this;return angular.forEach(arguments,function(b){a.rename(b,b+"_attributes")}),this},f.prototype.resource=function(a,b,c){return this.nestedResources[a]=b,c&&this.serializeWith(a,c),this},f.prototype.rename=function(b,c,d){return this.serializeMappings[b]=c,(d||d===a)&&(this.deserializeMappings[c]=b),this},f.prototype.add=function(a,b){return this.customSerializedAttributes[a]=b,this},f.prototype.preserve=function(a){return this.preservedAttributes[a]=!0,this},f.prototype.serializeWith=function(a,b){return this.customSerializers[a]=b,this},f.prototype.isExcludedFromSerialization=function(b){if(this.options.excludeByDefault&&!this.inclusions.hasOwnProperty(b)||this.exclusions.hasOwnProperty(b))return!0;if(this.options.exclusionMatchers){var c=!1;return angular.forEach(this.options.exclusionMatchers,function(d){angular.isString(d)?c=c||0===b.indexOf(d):angular.isFunction(d)?c=c||d.call(a,b):d instanceof RegExp&&(c=c||d.test(b))}),c}return!1},f.prototype.getSerializedAttributeName=function(b){var c=this.serializeMappings[b]||b;return this.isExcludedFromSerialization(b)||this.isExcludedFromSerialization(c)?a:this.underscore(c)},f.prototype.isExcludedFromDeserialization=function(){return!1},f.prototype.getDeserializedAttributeName=function(b){var c=this.camelize(b);return c=this.deserializeMappings[b]||this.deserializeMappings[c]||c,this.isExcludedFromDeserialization(b)||this.isExcludedFromDeserialization(c)?a:c},f.prototype.getNestedResource=function(a){return e.getDependency(this.nestedResources[a])},f.prototype.getAttributeSerializer=function(b){var c=this.getNestedResource(b),d=this.customSerializers[b];return d?e.createService(d):c?c.config.serializer:a},f.prototype.serializeValue=function(a){var b=a,c=this;if(angular.isArray(a))b=[],angular.forEach(a,function(a){b.push(c.serializeValue(a))});else if(angular.isObject(a)){if(angular.isDate(a))return a;b={},angular.forEach(a,function(a,d){angular.isFunction(a)||c.serializeAttribute(b,d,a)})}return b},f.prototype.serializeAttribute=function(b,c,d){var e=this.getAttributeSerializer(c),f=this.getSerializedAttributeName(c);f!==a&&(b[f]=e?e.serialize(d):this.serializeValue(d))},f.prototype.serialize=function(a){var b=this.serializeValue(a),c=this;return angular.isObject(b)&&angular.forEach(this.customSerializedAttributes,function(d,e){angular.isFunction(d)&&(d=d.call(a,a)),c.serializeAttribute(b,e,d)}),b},f.prototype.deserializeValue=function(a,b){var c=a,d=this;if(angular.isArray(a))c=[],angular.forEach(a,function(a){c.push(d.deserializeValue(a,b))});else if(angular.isObject(a)){if(angular.isDate(a))return a;c={},b&&(c=new b.config.resourceConstructor),angular.forEach(a,function(a,b){d.deserializeAttribute(c,b,a)})}return c},f.prototype.deserializeAttribute=function(b,c,d){var e,f,g=this.getDeserializedAttributeName(c);g!==a&&(e=this.getAttributeSerializer(g),f=this.getNestedResource(g),b[g]=this.preservedAttributes[g]?d:e?e.deserialize(d,f):this.deserializeValue(d,f))},f.prototype.deserialize=function(a,b){return this.deserializeValue(a,b)},f.prototype.pluralize=function(a){return this.options.pluralize?this.options.pluralize(a):a},f.prototype.underscore=function(a){return this.options.underscore?this.options.underscore(a):a},f.prototype.camelize=function(a){return this.options.camelize?this.options.camelize(a):a},f}return b.underscore=b.underscore||d.underscore,b.camelize=b.camelize||d.camelize,b.pluralize=b.pluralize||d.pluralize,f.defaultOptions=b,f}]})}(),function(a){angular.module("rails").factory("railsRootWrappingTransformer",function(){return function(a,b){var c={};return c[angular.isArray(a)?b.config.pluralName:b.config.name]=a,c}}),angular.module("rails").factory("railsRootWrappingInterceptor",function(){return function(a){var b=a.resource;return b?a.then(function(a){return a.data&&a.data.hasOwnProperty(b.config.name)?a.data=a.data[b.config.name]:a.data&&a.data.hasOwnProperty(b.config.pluralName)&&(a.data=a.data[b.config.pluralName]),a}):a}}),angular.module("rails").provider("RailsResource",function(){var b={rootWrapping:!0,updateMethod:"put",httpConfig:{},defaultParams:a};this.rootWrapping=function(a){return b.rootWrapping=a,this},this.updateMethod=function(a){return b.updateMethod=a,this},this.httpConfig=function(a){return b.httpConfig=a,this},this.defaultParams=function(a){return b.defaultParams=a,this},this.$get=["$http","$q","railsUrlBuilder","railsSerializer","railsRootWrappingTransformer","railsRootWrappingInterceptor","RailsResourceInjector",function(c,d,e,f,g,h,i){function j(a,b){return b&&("/"!==b[0]&&(a+="/"),a+=b),a}function k(a,b){for(var c,d=0,e=a.length;e>d;d++)c=a[d],angular.isString(c)&&(c=a[d]=i.getDependency(c)),b(c)}function l(a){var b=this;if(a){var c=function(a){return{resource:l,context:b,response:a,then:function(a){return this.response=a(this.response,this.resource,this.context),c(this.response)}}},d=this.constructor.callInterceptors(c({data:a}),this).response.data;angular.extend(this,d)}}return l.extend=function(a){function b(){this.constructor=a}var c={}.hasOwnProperty,d=this;for(var e in d)c.call(d,e)&&(a[e]=d[e]);return b.prototype=d.prototype,a.prototype=new b,a.__super__=d.prototype,a},l.configure=function(c){c=c||{},this.config&&(c=angular.extend({},this.config,c)),this.config={},this.config.url=c.url,this.config.rootWrapping=c.rootWrapping===a?b.rootWrapping:c.rootWrapping,this.config.httpConfig=c.httpConfig||b.httpConfig,this.config.httpConfig.headers=angular.extend({Accept:"application/json","Content-Type":"application/json"},this.config.httpConfig.headers||{}),this.config.defaultParams=c.defaultParams||b.defaultParams,this.config.updateMethod=(c.updateMethod||b.updateMethod).toLowerCase(),this.config.requestTransformers=c.requestTransformers?c.requestTransformers.slice(0):[],this.config.responseInterceptors=c.responseInterceptors?c.responseInterceptors.slice(0):[],this.config.afterResponseInterceptors=c.afterResponseInterceptors?c.afterResponseInterceptors.slice(0):[],this.config.serializer=angular.isObject(c.serializer)?c.serializer:i.createService(c.serializer||f()),this.config.name=this.config.serializer.underscore(c.name),this.config.pluralName=this.config.serializer.underscore(c.pluralName||this.config.serializer.pluralize(this.config.name)),this.config.urlBuilder=e(this.config.url),this.config.resourceConstructor=this},l.configure({}),l.setUrl=function(a){this.configure({url:a})},l.buildUrl=function(a){return this.config.urlBuilder(a)},l.beforeResponse=function(a){a=i.getDependency(a),this.config.responseInterceptors.push(function(b){return b.then(function(c){return a(c.data,b.resource.config.resourceConstructor,b.context),c})})},l.afterResponse=function(a){a=i.getDependency(a),this.config.afterResponseInterceptors.push(function(b){return b.then(function(c){return a(c,b.resource.config.resourceConstructor),c})})},l.beforeRequest=function(a){a=i.getDependency(a),this.config.requestTransformers.push(function(b,c){return a(b,c.config.resourceConstructor)||b})},l.transformData=function(a){var b=this.config;return a=b.serializer.serialize(a),k(this.config.requestTransformers,function(c){a=c(a,b.resourceConstructor)}),b.rootWrapping&&(a=g(a,b.resourceConstructor)),a},l.callInterceptors=function(a,b){var c=this.config;return a=a.then(function(a){return a.originalData=a.data,a}),c.rootWrapping&&(a.resource=c.resourceConstructor,a=h(a)),a.then(function(a){return a.data=c.serializer.deserialize(a.data,c.resourceConstructor),a}),k(c.responseInterceptors,function(d){a.resource=c.resourceConstructor,a.context=b,a=d(a)}),a},l.callAfterInterceptors=function(a){var b=this.config;return k(b.afterResponseInterceptors,function(c){a.resource=b.resourceConstructor,a=c(a)}),a},l.processResponse=function(a){return a=this.callInterceptors(a).then(function(a){return a.data}),this.callAfterInterceptors(a)},l.getParameters=function(a){var b;return this.config.defaultParams&&(b=this.config.defaultParams),angular.isObject(a)&&(b=angular.extend(b||{},a)),b},l.getHttpConfig=function(a){var b=this.getParameters(a);return b?angular.extend({params:b},this.config.httpConfig):angular.copy(this.config.httpConfig)},l.$url=l.resourceUrl=function(a,b){return angular.isObject(a)||(a={id:a}),j(this.buildUrl(a||{}),b)},l.$get=function(a,b){return this.processResponse(c.get(a,this.getHttpConfig(b)))},l.query=function(a,b){return this.$get(this.resourceUrl(b),a)},l.get=function(a,b){return this.$get(this.resourceUrl(a),b)},l.prototype.$url=function(a){return j(this.constructor.resourceUrl(this),a)},l.prototype.processResponse=function(a){return a=this.constructor.callInterceptors(a,this),a=a.then(angular.bind(this,function(a){return a.hasOwnProperty("data")&&angular.isObject(a.data)&&angular.extend(this,a.data),this})),this.constructor.callAfterInterceptors(a)},angular.forEach(["post","put","patch"],function(a){l["$"+a]=function(b,d){var e;return d=this.transformData(angular.copy(d,{})),e=angular.extend({method:a,url:b,data:d},this.getHttpConfig()),this.processResponse(c(e))},l.prototype["$"+a]=function(b){var d,e;return d=this.constructor.transformData(angular.copy(this,{})),e=angular.extend({method:a,url:b,data:d},this.constructor.getHttpConfig()),this.processResponse(c(e))}}),l.prototype.create=function(){return this.$post(this.$url(),this)},l.prototype.update=function(){return this["$"+this.constructor.config.updateMethod](this.$url(),this)},l.prototype.isNew=function(){return null==this.id},l.prototype.save=function(){return this.isNew()?this.create():this.update()},l.$delete=function(a){return this.processResponse(c["delete"](a,this.getHttpConfig()))},l.prototype.$delete=function(a){return this.processResponse(c["delete"](a,this.constructor.getHttpConfig()))},l.prototype.remove=l.prototype["delete"]=function(){return this.$delete(this.$url())},l}]}),angular.module("rails").factory("railsResourceFactory",["RailsResource",function(a){return function(b){function c(){c.__super__.constructor.apply(this,arguments)}return a.extend(c),c.configure(b),c}}])}();
7
+ !function(){angular.module("rails",["ng"])}(),function(){angular.module("rails").factory("RailsInflector",function(){function a(a){return angular.isString(a)?a.replace(/_[\w\d]/g,function(a,b,c){return 0===b?a:c.charAt(b+1).toUpperCase()}):a}function b(a){return angular.isString(a)?a.replace(/[A-Z]/g,function(a,b){return 0===b?a:"_"+a.toLowerCase()}):a}function c(a){return a+"s"}return{camelize:a,underscore:b,pluralize:c}})}(),function(a){angular.module("rails").factory("RailsResourceInjector",["$injector",function(b){function c(c){return c?angular.isString(c)?b.get(c):c:a}function d(d){return d?b.instantiate(c(d)):a}return{createService:d,getDependency:c}}])}(),function(){angular.module("rails").factory("railsUrlBuilder",["$interpolate",function(a){return function(b){var c;return angular.isFunction(b)||angular.isUndefined(b)?b:(-1===b.indexOf(a.startSymbol())&&(b=b+"/"+a.startSymbol()+"id"+a.endSymbol()),c=a(b),function(a){return b=c(a),"/"===b.charAt(b.length-1)&&(b=b.substr(0,b.length-1)),b})}}])}(),function(a){angular.module("rails").provider("railsSerializer",function(){var b={underscore:a,camelize:a,pluralize:a,exclusionMatchers:[]};this.underscore=function(a){return b.underscore=a,this},this.camelize=function(a){return b.camelize=a,this},this.pluralize=function(a){return b.pluralize=a,this},this.exclusionMatchers=function(a){return b.exclusionMatchers=a,this},this.$get=["$injector","RailsInflector","RailsResourceInjector",function(c,d,e){function f(c,d){function f(){angular.isFunction(c)&&(d=c,c={}),this.exclusions={},this.inclusions={},this.serializeMappings={},this.deserializeMappings={},this.customSerializedAttributes={},this.preservedAttributes={},this.customSerializers={},this.nestedResources={},this.options=angular.extend({excludeByDefault:!1},b,c||{}),d&&d.call(this,this)}return f.prototype.exclude=function(){var a=this.exclusions;return angular.forEach(arguments,function(b){a[b]=!1}),this},f.prototype.only=function(){var a=this.inclusions;return this.options.excludeByDefault=!0,angular.forEach(arguments,function(b){a[b]=!0}),this},f.prototype.nestedAttribute=function(){var a=this;return angular.forEach(arguments,function(b){a.rename(b,b+"_attributes")}),this},f.prototype.resource=function(a,b,c){return this.nestedResources[a]=b,c&&this.serializeWith(a,c),this},f.prototype.rename=function(b,c,d){return this.serializeMappings[b]=c,(d||d===a)&&(this.deserializeMappings[c]=b),this},f.prototype.add=function(a,b){return this.customSerializedAttributes[a]=b,this},f.prototype.preserve=function(a){return this.preservedAttributes[a]=!0,this},f.prototype.serializeWith=function(a,b){return this.customSerializers[a]=b,this},f.prototype.isExcludedFromSerialization=function(b){if(this.options.excludeByDefault&&!this.inclusions.hasOwnProperty(b)||this.exclusions.hasOwnProperty(b))return!0;if(this.options.exclusionMatchers){var c=!1;return angular.forEach(this.options.exclusionMatchers,function(d){angular.isString(d)?c=c||0===b.indexOf(d):angular.isFunction(d)?c=c||d.call(a,b):d instanceof RegExp&&(c=c||d.test(b))}),c}return!1},f.prototype.getSerializedAttributeName=function(b){var c=this.serializeMappings[b]||b,d=this.isExcludedFromSerialization(c),e=this.isExcludedFromSerialization(b);if(this.options.excludeByDefault){if(d&&e)return a}else if(d||e)return a;return this.underscore(c)},f.prototype.isExcludedFromDeserialization=function(){return!1},f.prototype.getDeserializedAttributeName=function(b){var c=this.camelize(b);return c=this.deserializeMappings[b]||this.deserializeMappings[c]||c,this.isExcludedFromDeserialization(b)||this.isExcludedFromDeserialization(c)?a:c},f.prototype.getNestedResource=function(a){return e.getDependency(this.nestedResources[a])},f.prototype.getAttributeSerializer=function(b){var c=this.getNestedResource(b),d=this.customSerializers[b];return d?e.createService(d):c?c.config.serializer:a},f.prototype.serializeValue=function(a){var b=a,c=this;if(angular.isArray(a))b=[],angular.forEach(a,function(a){b.push(c.serializeValue(a))});else if(angular.isObject(a)){if(angular.isDate(a))return a;b={},angular.forEach(a,function(a,d){angular.isFunction(a)||c.serializeAttribute(b,d,a)})}return b},f.prototype.serializeAttribute=function(b,c,d){var e=this.getAttributeSerializer(c),f=this.getSerializedAttributeName(c);f!==a&&(b[f]=e?e.serialize(d):this.serializeValue(d))},f.prototype.serialize=function(a){var b=this.serializeValue(a),c=this;return angular.isObject(b)&&angular.forEach(this.customSerializedAttributes,function(d,e){angular.isFunction(d)&&(d=d.call(a,a)),c.serializeAttribute(b,e,d)}),b},f.prototype.deserializeValue=function(a,b){var c=a,d=this;if(angular.isArray(a))c=[],angular.forEach(a,function(a){c.push(d.deserializeValue(a,b))});else if(angular.isObject(a)){if(angular.isDate(a))return a;c={},b&&(c=new b.config.resourceConstructor),angular.forEach(a,function(a,b){d.deserializeAttribute(c,b,a)})}return c},f.prototype.deserializeAttribute=function(b,c,d){var e,f,g=this.getDeserializedAttributeName(c);g!==a&&(e=this.getAttributeSerializer(g),f=this.getNestedResource(g),b[g]=this.preservedAttributes[g]?d:e?e.deserialize(d,f):this.deserializeValue(d,f))},f.prototype.deserialize=function(a,b){return this.deserializeValue(a,b)},f.prototype.pluralize=function(a){return this.options.pluralize?this.options.pluralize(a):a},f.prototype.underscore=function(a){return this.options.underscore?this.options.underscore(a):a},f.prototype.camelize=function(a){return this.options.camelize?this.options.camelize(a):a},f}return b.underscore=b.underscore||d.underscore,b.camelize=b.camelize||d.camelize,b.pluralize=b.pluralize||d.pluralize,f.defaultOptions=b,f}]})}(),function(a){angular.module("rails").factory("railsRootWrappingTransformer",function(){return function(a,b){var c={};return c[angular.isArray(a)?b.config.pluralName:b.config.name]=a,c}}),angular.module("rails").factory("railsRootWrappingInterceptor",function(){return function(a){var b=a.resource;return b?a.then(function(a){return a.data&&a.data.hasOwnProperty(b.config.name)?a.data=a.data[b.config.name]:a.data&&a.data.hasOwnProperty(b.config.pluralName)&&(a.data=a.data[b.config.pluralName]),a}):a}}),angular.module("rails").provider("RailsResource",function(){var b={rootWrapping:!0,updateMethod:"put",httpConfig:{},defaultParams:a};this.rootWrapping=function(a){return b.rootWrapping=a,this},this.updateMethod=function(a){return b.updateMethod=a,this},this.httpConfig=function(a){return b.httpConfig=a,this},this.defaultParams=function(a){return b.defaultParams=a,this},this.$get=["$http","$q","railsUrlBuilder","railsSerializer","railsRootWrappingTransformer","railsRootWrappingInterceptor","RailsResourceInjector",function(c,d,e,f,g,h,i){function j(a,b){return b&&("/"!==b[0]&&(a+="/"),a+=b),a}function k(a,b){for(var c,d=0,e=a.length;e>d;d++)c=a[d],angular.isString(c)&&(c=a[d]=i.getDependency(c)),b(c)}function l(a){var b=this;if(a){var c=function(a){return{resource:l,context:b,response:a,then:function(a){return this.response=a(this.response,this.resource,this.context),c(this.response)}}},d=this.constructor.callInterceptors(c({data:a}),this).response.data;angular.extend(this,d)}}return l.extend=function(a){function b(){this.constructor=a}var c={}.hasOwnProperty,d=this;for(var e in d)c.call(d,e)&&(a[e]=d[e]);return b.prototype=d.prototype,a.prototype=new b,a.__super__=d.prototype,a},l.configure=function(c){c=c||{},this.config&&(c=angular.extend({},this.config,c)),this.config={},this.config.url=c.url,this.config.rootWrapping=c.rootWrapping===a?b.rootWrapping:c.rootWrapping,this.config.httpConfig=c.httpConfig||b.httpConfig,this.config.httpConfig.headers=angular.extend({Accept:"application/json","Content-Type":"application/json"},this.config.httpConfig.headers||{}),this.config.defaultParams=c.defaultParams||b.defaultParams,this.config.updateMethod=(c.updateMethod||b.updateMethod).toLowerCase(),this.config.requestTransformers=c.requestTransformers?c.requestTransformers.slice(0):[],this.config.responseInterceptors=c.responseInterceptors?c.responseInterceptors.slice(0):[],this.config.afterResponseInterceptors=c.afterResponseInterceptors?c.afterResponseInterceptors.slice(0):[],this.config.serializer=angular.isObject(c.serializer)?c.serializer:i.createService(c.serializer||f()),this.config.name=this.config.serializer.underscore(c.name),this.config.name&&(this.config.pluralName=this.config.serializer.underscore(c.pluralName||this.config.serializer.pluralize(this.config.name))),this.config.urlBuilder=e(this.config.url),this.config.resourceConstructor=this},l.configure({}),l.setUrl=function(a){this.configure({url:a})},l.buildUrl=function(a){return this.config.urlBuilder(a)},l.beforeResponse=function(a){a=i.getDependency(a),this.config.responseInterceptors.push(function(b){return b.then(function(c){return a(c.data,b.resource.config.resourceConstructor,b.context),c})})},l.afterResponse=function(a){a=i.getDependency(a),this.config.afterResponseInterceptors.push(function(b){return b.then(function(c){return a(c,b.resource.config.resourceConstructor),c})})},l.beforeRequest=function(a){a=i.getDependency(a),this.config.requestTransformers.push(function(b,c){return a(b,c.config.resourceConstructor)||b})},l.transformData=function(a){var b=this.config;return a=b.serializer.serialize(a),k(this.config.requestTransformers,function(c){a=c(a,b.resourceConstructor)}),b.rootWrapping&&(a=g(a,b.resourceConstructor)),a},l.callInterceptors=function(a,b){var c=this.config;return a=a.then(function(a){return a.originalData=a.data,a}),c.rootWrapping&&(a.resource=c.resourceConstructor,a=h(a)),a.then(function(a){return a.data=c.serializer.deserialize(a.data,c.resourceConstructor),a}),k(c.responseInterceptors,function(d){a.resource=c.resourceConstructor,a.context=b,a=d(a)}),a},l.callAfterInterceptors=function(a){var b=this.config;return k(b.afterResponseInterceptors,function(c){a.resource=b.resourceConstructor,a=c(a)}),a},l.processResponse=function(a){return a=this.callInterceptors(a).then(function(a){return a.data}),this.callAfterInterceptors(a)},l.getParameters=function(a){var b;return this.config.defaultParams&&(b=this.config.defaultParams),angular.isObject(a)&&(b=angular.extend(b||{},a)),b},l.getHttpConfig=function(a){var b=this.getParameters(a);return b?angular.extend({params:b},this.config.httpConfig):angular.copy(this.config.httpConfig)},l.$url=l.resourceUrl=function(a,b){return angular.isObject(a)||(a={id:a}),j(this.buildUrl(a||{}),b)},l.$get=function(a,b){return this.processResponse(c.get(a,this.getHttpConfig(b)))},l.query=function(a,b){return this.$get(this.resourceUrl(b),a)},l.get=function(a,b){return this.$get(this.resourceUrl(a),b)},l.prototype.$url=function(a){return j(this.constructor.resourceUrl(this),a)},l.prototype.processResponse=function(a){return a=this.constructor.callInterceptors(a,this),a=a.then(angular.bind(this,function(a){return a.hasOwnProperty("data")&&angular.isObject(a.data)&&angular.extend(this,a.data),this})),this.constructor.callAfterInterceptors(a)},angular.forEach(["post","put","patch"],function(a){l["$"+a]=function(b,d){var e;return d=this.transformData(angular.copy(d)),e=angular.extend({method:a,url:b,data:d},this.getHttpConfig()),this.processResponse(c(e))},l.prototype["$"+a]=function(b){var d,e;return d=this.constructor.transformData(angular.copy(this,{})),e=angular.extend({method:a,url:b,data:d},this.constructor.getHttpConfig()),this.processResponse(c(e))}}),l.prototype.create=function(){return this.$post(this.$url(),this)},l.prototype.update=function(){return this["$"+this.constructor.config.updateMethod](this.$url(),this)},l.prototype.isNew=function(){return null==this.id},l.prototype.save=function(){return this.isNew()?this.create():this.update()},l.$delete=function(a){return this.processResponse(c["delete"](a,this.getHttpConfig()))},l.prototype.$delete=function(a){return this.processResponse(c["delete"](a,this.constructor.getHttpConfig()))},l.prototype.remove=l.prototype["delete"]=function(){return this.$delete(this.$url())},l}]}),angular.module("rails").factory("railsResourceFactory",["RailsResource",function(a){return function(b){function c(){c.__super__.constructor.apply(this,arguments)}return a.extend(c),c.configure(b),c}}])}();
Binary file
data/bower.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "angularjs-rails-resource",
3
- "version": "1.0.0-pre1",
3
+ "version": "1.0.0-pre.2",
4
4
  "main": "angularjs-rails-resource.js",
5
5
  "description": "A resource factory inspired by $resource from AngularJS",
6
6
  "repository": {
@@ -1,7 +1,7 @@
1
1
  module Angularjs
2
2
  module Rails
3
3
  module Resource
4
- VERSION = '1.0.0.pre.1'
4
+ VERSION = '1.0.0.pre.2'
5
5
  end
6
6
  end
7
7
  end
data/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "angularjs-rails-resource",
3
3
  "description" : "A resource factory inspired by $resource from AngularJS",
4
- "version": "1.0.0-pre1",
4
+ "version": "1.0.0-pre.2",
5
5
  "main" : "dist/angularjs-rails-resource.min.js",
6
6
  "homepage" : "https://github.com/FineLinePrototyping/angularjs-rails-resource.git",
7
7
  "author" : "",
@@ -426,6 +426,14 @@ describe('railsResourceFactory', function () {
426
426
  expect(test).toEqualData({id: 123, abc: 'xyz', xyz: 'abc', extra: 'test'});
427
427
  }));
428
428
  });
429
+
430
+ it('should be able to $post an array of resources', function () {
431
+ var data = [{id: 123, abc: 'xyz'}, {id: 124, abc: 'xyz'}];
432
+ $httpBackend['expectPOST']('/xyz', {tests: data} ).respond(200, {tests: data});
433
+ Test.$post('/xyz', data);
434
+ $httpBackend.flush();
435
+ });
436
+
429
437
  });
430
438
 
431
439
  describe('plural', function() {
@@ -390,6 +390,22 @@ describe('railsSerializer', function () {
390
390
  result = serializer.deserialize({id: 1, first: 'George', middle: 'R. R.', last: 'Martin'});
391
391
  expect(result).toEqualData({id: 1, first: 'George', middle: 'R. R.', last: 'Martin'});
392
392
  });
393
+
394
+ it('should only serialize id and books', function() {
395
+ var result,
396
+ serializer = createSerializer(function(config) {
397
+ this.only('id', 'books');
398
+ this.nestedAttribute('books');
399
+ this.serializeWith('books', factory(function() { }));
400
+ });
401
+ var book = { id: 1, title: 'A Game of Thrones', publicationDate: '1996-08-06' };
402
+ result = serializer.serialize({
403
+ id: 1, first: 'George', last: 'Martin', books: [book]
404
+ });
405
+ expect(result).toEqualData({ id: 1, books_attributes: [{ id: 1, title: 'A Game of Thrones', publication_date: '1996-08-06' }] });
406
+ result = serializer.deserialize(result);
407
+ expect(result).toEqual({ id: 1, books: [book]});
408
+ });
393
409
  });
394
410
  });
395
411
  });
@@ -149,7 +149,11 @@
149
149
  }
150
150
 
151
151
  this.config.name = this.config.serializer.underscore(cfg.name);
152
- this.config.pluralName = this.config.serializer.underscore(cfg.pluralName || this.config.serializer.pluralize(this.config.name));
152
+
153
+ // we don't want to turn undefined name into "undefineds" then the plural name won't update when the name is set
154
+ if (this.config.name) {
155
+ this.config.pluralName = this.config.serializer.underscore(cfg.pluralName || this.config.serializer.pluralize(this.config.name));
156
+ }
153
157
 
154
158
  this.config.urlBuilder = railsUrlBuilder(this.config.url);
155
159
  this.config.resourceConstructor = this;
@@ -360,7 +364,7 @@
360
364
  RailsResource['$' + method] = function (url, data) {
361
365
  var config;
362
366
  // clone so we can manipulate w/o modifying the actual instance
363
- data = this.transformData(angular.copy(data, {}));
367
+ data = this.transformData(angular.copy(data));
364
368
  config = angular.extend({method: method, url: url, data: data}, this.getHttpConfig());
365
369
  return this.processResponse($http(config));
366
370
  };
@@ -263,8 +263,17 @@
263
263
  Serializer.prototype.getSerializedAttributeName = function (attributeName) {
264
264
  var mappedName = this.serializeMappings[attributeName] || attributeName;
265
265
 
266
- if (this.isExcludedFromSerialization(attributeName) || this.isExcludedFromSerialization(mappedName)) {
267
- return undefined;
266
+ var mappedNameExcluded = this.isExcludedFromSerialization(mappedName),
267
+ attributeNameExcluded = this.isExcludedFromSerialization(attributeName);
268
+
269
+ if(this.options.excludeByDefault) {
270
+ if(mappedNameExcluded && attributeNameExcluded) {
271
+ return undefined;
272
+ }
273
+ } else {
274
+ if (mappedNameExcluded || attributeNameExcluded) {
275
+ return undefined;
276
+ }
268
277
  }
269
278
 
270
279
  return this.underscore(mappedName);
@@ -329,7 +338,7 @@
329
338
 
330
339
  // custom serializer takes precedence over resource serializer
331
340
  if (serializer) {
332
- return RailsResourceInjector.createService(serializer)
341
+ return RailsResourceInjector.createService(serializer);
333
342
  } else if (resource) {
334
343
  return resource.config.serializer;
335
344
  }
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: angularjs-rails-resource
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0.pre.1
4
+ version: 1.0.0.pre.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tommy Odom
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-10-15 00:00:00.000000000 Z
12
+ date: 2013-11-24 00:00:00.000000000 Z
13
13
  dependencies: []
14
14
  description: A small AngularJS add-on for integrating with Rails via JSON more easily.
15
15
  email: