ende 0.3.13 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (76) hide show
  1. checksums.yaml +4 -4
  2. data/component.json +7 -0
  3. data/lib/assets/javascripts/aura/extensions/devise.js.coffee +2 -2
  4. data/lib/assets/javascripts/aura/extensions/loader.js.coffee +13 -11
  5. data/lib/assets/javascripts/aura/extensions/mask.js.coffee +54 -40
  6. data/lib/assets/javascripts/aura/extensions/mediator.js +5 -3
  7. data/lib/assets/javascripts/aura/extensions/models.js.coffee.erb +2 -2
  8. data/lib/assets/javascripts/aura/extensions/rivets/accounting.js.coffee +7 -1
  9. data/lib/assets/javascripts/aura/extensions/rivets/formatters.js.coffee +5 -1
  10. data/lib/assets/javascripts/aura/extensions/rivets.js.coffee +47 -29
  11. data/lib/assets/javascripts/aura/extensions/routes.js.coffee +10 -5
  12. data/lib/assets/javascripts/aura/extensions/states.js.coffee +2 -2
  13. data/lib/assets/javascripts/aura/extensions/widget/eventable.js.coffee +18 -19
  14. data/lib/assets/javascripts/aura/extensions/widget/lifecycleable.js.coffee +15 -10
  15. data/lib/assets/javascripts/config/initializers/jquery.js.coffee +2 -1
  16. data/lib/assets/javascripts/config/initializers/requirejs.js.coffee +3 -4
  17. data/lib/assets/javascripts/config/initializers.js.coffee +3 -0
  18. data/lib/assets/javascripts/config/load_components.js.coffee +106 -83
  19. data/lib/assets/javascripts/ende.js.coffee +13 -4
  20. data/lib/assets/javascripts/widgets/authenticator/presenter.js.coffee +3 -2
  21. data/lib/assets/javascripts/widgets/dialog/main.js.coffee +7 -3
  22. data/lib/assets/javascripts/widgets/support/main.js.coffee +3 -4
  23. data/lib/assets/javascripts/widgets/viewer/main.js.coffee +35 -103
  24. data/lib/assets/javascripts/widgets/viewer/presenters/default.js.coffee +2 -4
  25. data/lib/ende/version.rb +1 -1
  26. data/vendor/assets/components/build.js +30877 -0
  27. data/vendor/assets/components/ende_build.js +2487 -148
  28. data/vendor/assets/components/indemma_with_none.js +30553 -0
  29. data/vendor/assets/javascripts/spin/spin.js +349 -0
  30. data/vendor/components/indefinido-indemma/.gitignore +3 -0
  31. data/vendor/components/indefinido-indemma/.ruby-gemset +1 -1
  32. data/vendor/components/indefinido-indemma/.ruby-version +1 -1
  33. data/vendor/components/indefinido-indemma/build/development.js +17 -14
  34. data/vendor/components/indefinido-indemma/build/release.js +213 -148
  35. data/vendor/components/indefinido-indemma/build/test.js +213 -148
  36. data/vendor/components/indefinido-indemma/component.json +3 -1
  37. data/vendor/components/indefinido-indemma/karma.conf.js +50 -60
  38. data/vendor/components/indefinido-indemma/lib/record/associable.js +17 -17
  39. data/vendor/components/indefinido-indemma/lib/record/persistable.js +8 -1
  40. data/vendor/components/indefinido-indemma/lib/record/queryable.js +3 -0
  41. data/vendor/components/indefinido-indemma/lib/record/resource.js +25 -45
  42. data/vendor/components/indefinido-indemma/lib/record/restfulable.js +82 -28
  43. data/vendor/components/indefinido-indemma/lib/record/scopable.js +28 -2
  44. data/vendor/components/indefinido-indemma/lib/record/storable.js +1 -1
  45. data/vendor/components/indefinido-indemma/lib/record/validatable.js +15 -23
  46. data/vendor/components/indefinido-indemma/lib/record/validations/associated.js +3 -5
  47. data/vendor/components/indefinido-indemma/lib/record/validations/confirmation.js +3 -5
  48. data/vendor/components/indefinido-indemma/lib/record/validations/cpf.js +5 -7
  49. data/vendor/components/indefinido-indemma/lib/record/validations/presence.js +3 -5
  50. data/vendor/components/indefinido-indemma/lib/record/validations/remote.js +3 -7
  51. data/vendor/components/indefinido-indemma/lib/record/validations/type.js +2 -2
  52. data/vendor/components/indefinido-indemma/lib/record/validations/validatorable.js +12 -0
  53. data/vendor/components/indefinido-indemma/package.json +9 -0
  54. data/vendor/components/indefinido-indemma/spec/record/restfulable_spec.js +12 -0
  55. data/vendor/components/indefinido-indemma/spec/record/validatable_spec.js +4 -4
  56. data/vendor/components/indefinido-indemma/spec/record/validations/associated_spec.js +2 -2
  57. data/vendor/components/indefinido-indemma/src/lib/record/associable.coffee +44 -20
  58. data/vendor/components/indefinido-indemma/src/lib/record/persistable.coffee +7 -2
  59. data/vendor/components/indefinido-indemma/src/lib/record/queryable.coffee +1 -0
  60. data/vendor/components/indefinido-indemma/src/lib/record/resource.coffee +32 -32
  61. data/vendor/components/indefinido-indemma/src/lib/record/restfulable.coffee +79 -22
  62. data/vendor/components/indefinido-indemma/src/lib/record/scopable.coffee +27 -8
  63. data/vendor/components/indefinido-indemma/src/lib/record/storable.coffee +1 -1
  64. data/vendor/components/indefinido-indemma/src/lib/record/validatable.coffee +20 -19
  65. data/vendor/components/indefinido-indemma/src/lib/record/validations/associated.coffee +3 -5
  66. data/vendor/components/indefinido-indemma/src/lib/record/validations/confirmation.coffee +2 -4
  67. data/vendor/components/indefinido-indemma/src/lib/record/validations/cpf.coffee +4 -5
  68. data/vendor/components/indefinido-indemma/src/lib/record/validations/presence.coffee +2 -5
  69. data/vendor/components/indefinido-indemma/src/lib/record/validations/remote.coffee +3 -7
  70. data/vendor/components/indefinido-indemma/src/lib/record/validations/type.coffee +2 -3
  71. data/vendor/components/indefinido-indemma/src/lib/record/validations/validatorable.coffee +5 -0
  72. data/vendor/components/indefinido-indemma/src/spec/record/restfulable_spec.coffee +8 -0
  73. data/vendor/components/indefinido-indemma/src/spec/record/validatable_spec.coffee +4 -4
  74. data/vendor/components/indefinido-indemma/src/spec/record/validations/associated_spec.coffee +2 -2
  75. metadata +9 -3
  76. data/lib/assets/javascripts/aura/extensions/rivets/formatters.js.coffee~ +0 -0
@@ -1,4 +1,4 @@
1
- var $, builders, defaults, extend, merge, model, record, rest, scopable, stampit,
1
+ var $, builders, defaults, extend, merge, model, observable, record, rest, scopable, stampit, util,
2
2
  __slice = [].slice;
3
3
 
4
4
  require('./restfulable');
@@ -9,12 +9,29 @@ stampit = require('../../vendor/stampit');
9
9
 
10
10
  extend = require('assimilate');
11
11
 
12
+ observable = require('observable').mixin;
13
+
12
14
  merge = extend.withStrategy('deep');
13
15
 
14
16
  $ = require('jquery');
15
17
 
16
18
  rest = require('./rest');
17
19
 
20
+ util = {
21
+ model: {
22
+ map: function(records) {
23
+ var index, record, _i, _len, _results;
24
+
25
+ _results = [];
26
+ for (index = _i = 0, _len = records.length; _i < _len; index = ++_i) {
27
+ record = records[index];
28
+ _results.push((this.build || this).call(this, record));
29
+ }
30
+ return _results;
31
+ }
32
+ }
33
+ };
34
+
18
35
  scopable = {
19
36
  builder: stampit().enclose(function() {
20
37
  return stampit.mixIn(function(name, type) {
@@ -45,14 +62,19 @@ scopable = {
45
62
  fetch: function(data, done, fail) {
46
63
  var deferred, scope;
47
64
 
65
+ if (typeof data === 'function') {
66
+ done = data;
67
+ data = {};
68
+ }
48
69
  scope = extend({}, this.scope.data);
70
+ observable.unobserve(scope);
49
71
  if (scope.noned != null) {
50
72
  deferred = $.Deferred();
51
73
  deferred.resolveWith(this, [[]]);
52
74
  } else {
53
75
  deferred = rest.get.call(this, extend(scope, data));
54
76
  }
55
- deferred.done(this.scope.then.concat(done)).fail([this.scope.fail, fail]);
77
+ deferred.then(util.model.map).done(this.scope.then.concat([done])).fail(this.scope.fail.concat([fail]));
56
78
  this.scope.clear();
57
79
  return deferred;
58
80
  },
@@ -95,6 +117,10 @@ scopable = {
95
117
  return this;
96
118
  },
97
119
  fetch: function(data, done, fail) {
120
+ if (typeof data === 'function') {
121
+ done = data;
122
+ data = null;
123
+ }
98
124
  return this.scope.fetch.call(this, data, done, fail);
99
125
  },
100
126
  forward_scopes_to_associations: function() {
@@ -23,7 +23,7 @@ storable = stampit({
23
23
  return collection[key];
24
24
  } else {
25
25
  this.writes++;
26
- value.sustained = true;
26
+ value.sustained || (value.sustained = true);
27
27
  return collection[key] = value;
28
28
  }
29
29
  },
@@ -1,8 +1,8 @@
1
- var errorsable, extensions, initializers, manager, messages, observable, root, stampit, type, validatable;
1
+ var errorsable, extensions, initializers, manager, messages, observable, root, stampit, type;
2
2
 
3
3
  require('./translationable');
4
4
 
5
- root = typeof exports !== "undefined" && exports !== null ? exports : window;
5
+ root = typeof exports !== "undefined" && exports !== null ? exports : this;
6
6
 
7
7
  stampit = require('../../vendor/stampit');
8
8
 
@@ -93,7 +93,7 @@ initializers = {
93
93
  });
94
94
  this.validated = false;
95
95
  this.subscribe('dirty', function(value) {
96
- return this.validated = false;
96
+ return value && (this.validated = false);
97
97
  });
98
98
  return Object.defineProperty(this, 'valid', {
99
99
  get: function() {
@@ -187,7 +187,12 @@ extensions = {
187
187
  this.validation.done(doned);
188
188
  this.validation.fail(failed);
189
189
  this.validation.then(function(record) {
190
- return record.validated = true;
190
+ var old_dirty;
191
+
192
+ old_dirty = record.dirty;
193
+ record.dirty = null;
194
+ record.validated || (record.validated = true);
195
+ return record.dirty = old_dirty;
191
196
  });
192
197
  return this.validation;
193
198
  }
@@ -198,15 +203,6 @@ manager = {
198
203
  validators: {}
199
204
  };
200
205
 
201
- validatable = stampit({
202
- validate: function() {
203
- throw new Error('Composed factory must override the validate method');
204
- },
205
- validate_each: function() {
206
- throw new Error('Composed factory must override the validate each method');
207
- }
208
- });
209
-
210
206
  model.mix(function(modelable) {
211
207
  jQuery.extend(modelable, extensions.model);
212
208
  jQuery.extend(modelable.record, extensions.record);
@@ -215,18 +211,14 @@ model.mix(function(modelable) {
215
211
  return model.validators = manager.validators;
216
212
  });
217
213
 
218
- root.validatable = validatable;
219
-
220
- root.manager = manager;
221
-
222
- require('./validations/confirmation');
214
+ manager.validators.confirmation = require('./validations/confirmation');
223
215
 
224
- require('./validations/associated');
216
+ manager.validators.associated = require('./validations/associated');
225
217
 
226
- require('./validations/presence');
218
+ manager.validators.presence = require('./validations/presence');
227
219
 
228
- require('./validations/remote');
220
+ manager.validators.remote = require('./validations/remote');
229
221
 
230
- require('./validations/type');
222
+ manager.validators.type = require('./validations/type');
231
223
 
232
- require('./validations/cpf');
224
+ manager.validators.cpf = require('./validations/cpf');
@@ -1,6 +1,4 @@
1
- var associationable, composed, stampit, validations;
2
-
3
- validations = require('../validatable');
1
+ var associationable, composed, stampit;
4
2
 
5
3
  stampit = require('../../../vendor/stampit');
6
4
 
@@ -23,8 +21,8 @@ associationable = stampit({
23
21
  }
24
22
  });
25
23
 
26
- composed = stampit.compose(validations.validatable, associationable);
24
+ composed = stampit.compose(require('./validatorable'), associationable);
27
25
 
28
26
  composed.definition_key = 'validates_associated';
29
27
 
30
- validations.manager.validators.association = composed;
28
+ module.exports = composed;
@@ -1,6 +1,4 @@
1
- var composed, confirmationable, stampit, validations;
2
-
3
- validations = require('../validatable');
1
+ var composed, confirmationable, stampit;
4
2
 
5
3
  stampit = require('../../../vendor/stampit');
6
4
 
@@ -12,8 +10,8 @@ confirmationable = stampit({
12
10
  }
13
11
  });
14
12
 
15
- composed = stampit.compose(validations.validatable, confirmationable);
13
+ composed = stampit.compose(require('./validatorable'), confirmationable);
16
14
 
17
15
  composed.definition_key = 'validates_confirmation_of';
18
16
 
19
- validations.manager.validators.confirmation = composed;
17
+ module.exports = composed;
@@ -1,6 +1,4 @@
1
- var composed, cpfable, stampit, validations;
2
-
3
- validations = require('../validatable');
1
+ var composed, cpfable, stampit;
4
2
 
5
3
  stampit = require('../../../vendor/stampit');
6
4
 
@@ -20,7 +18,7 @@ cpfable = stampit({
20
18
  d1 = 0;
21
19
  v = false;
22
20
  i = 0;
23
- for (i = _i = 1; _i <= 9; i = ++_i) {
21
+ for (i = _i = 0; _i <= 9; i = ++_i) {
24
22
  d1 += c.charAt(i) * (10 - i);
25
23
  }
26
24
  if (d1 === 0) {
@@ -34,7 +32,7 @@ cpfable = stampit({
34
32
  return false;
35
33
  }
36
34
  d1 *= 2;
37
- for (i = _j = 1; _j <= 9; i = ++_j) {
35
+ for (i = _j = 0; _j <= 9; i = ++_j) {
38
36
  d1 += c.charAt(i) * (11 - i);
39
37
  }
40
38
  d1 = 11 - (d1 % 11);
@@ -53,8 +51,8 @@ cpfable = stampit({
53
51
  }
54
52
  });
55
53
 
56
- composed = stampit.compose(validations.validatable, cpfable);
54
+ composed = stampit.compose(require('./validatorable'), cpfable);
57
55
 
58
56
  composed.definition_key = 'validates_cpf_format';
59
57
 
60
- validations.manager.validators.cpf = composed;
58
+ module.exports = composed;
@@ -1,6 +1,4 @@
1
- var composed, presenceable, stampit, validations;
2
-
3
- validations = require('../validatable');
1
+ var composed, presenceable, stampit;
4
2
 
5
3
  stampit = require('../../../vendor/stampit');
6
4
 
@@ -12,8 +10,8 @@ presenceable = stampit({
12
10
  }
13
11
  });
14
12
 
15
- composed = stampit.compose(validations.validatable, presenceable);
13
+ composed = stampit.compose(require('./validatorable'), presenceable);
16
14
 
17
15
  composed.definition_key = 'validates_presence_of';
18
16
 
19
- validations.manager.validators.presence = composed;
17
+ module.exports = composed;
@@ -1,8 +1,4 @@
1
- var composed, remoteable, rest, root, stampit, validations;
2
-
3
- root = typeof exports !== "undefined" && exports !== null ? exports : window;
4
-
5
- validations = require('../validatable');
1
+ var composed, remoteable, rest, stampit;
6
2
 
7
3
  rest = require('../rest');
8
4
 
@@ -65,8 +61,8 @@ remoteable = stampit({
65
61
  return this;
66
62
  });
67
63
 
68
- composed = stampit.compose(validations.validatable, remoteable);
64
+ composed = stampit.compose(require('./validatorable'), remoteable);
69
65
 
70
66
  composed.definition_key = 'validates_remotely';
71
67
 
72
- validations.manager.validators.remote = composed;
68
+ module.exports = composed;
@@ -22,8 +22,8 @@ typeable = stampit({
22
22
  }
23
23
  });
24
24
 
25
- composed = stampit.compose(validations.validatable, typeable);
25
+ composed = stampit.compose(require('./validatorable'), typeable);
26
26
 
27
27
  composed.definition_key = 'validates_type_of';
28
28
 
29
- validations.manager.validators.type = composed;
29
+ module.exports = composed;
@@ -0,0 +1,12 @@
1
+ var stampit;
2
+
3
+ stampit = require('../../../vendor/stampit');
4
+
5
+ module.exports = stampit({
6
+ validate: function() {
7
+ throw new Error('Composed factory must override the validate method');
8
+ },
9
+ validate_each: function() {
10
+ throw new Error('Composed factory must override the validate each method');
11
+ }
12
+ });
@@ -0,0 +1,9 @@
1
+ {
2
+ "name": "indemma",
3
+ "version": "0.1.7",
4
+ "devDependencies": {
5
+ "mocha": "*",
6
+ "karma": "~0.10",
7
+ "karma-mocha": "~0.1"
8
+ }
9
+ }
@@ -121,6 +121,18 @@ describe('restfulable', function() {
121
121
  belongs_to: 'person'
122
122
  });
123
123
  });
124
+ it('should not assign attribute with the same value twice', function() {
125
+ var arthur, object;
126
+
127
+ object = {};
128
+ arthur = person({
129
+ name: object
130
+ });
131
+ arthur.assign_attributes({
132
+ name: {}
133
+ });
134
+ return arthur.name.should.not.be.eq(object);
135
+ });
124
136
  return it('assigns associations properly', function() {
125
137
  var arthur, attributes, ford, marvin, search_record;
126
138
 
@@ -18,9 +18,9 @@ describe('model', function() {
18
18
  person.should.have.property('validators');
19
19
  return person.validators.should.be.an('array');
20
20
  });
21
- return describe('#()', function() {
21
+ return describe('(validates_... : ...)', function() {
22
22
  describe('validators instatiation', function() {
23
- it('should instantiate validators with prefix validates_', function() {
23
+ it('should have validators', function() {
24
24
  var validator;
25
25
 
26
26
  person = model.call({
@@ -32,9 +32,9 @@ describe('model', function() {
32
32
  validator = person.validators[0];
33
33
  return validator.should.have.property('attribute_name', 'name');
34
34
  });
35
- return it('should instantiate validators with in the key validates');
35
+ return it('should have validators with in the key validates');
36
36
  });
37
- describe('#validate_attribute', function() {
37
+ describe('.validate_attribute()', function() {
38
38
  beforeEach(function() {
39
39
  person.validators.length = 0;
40
40
  return person = model.call({
@@ -4,7 +4,7 @@ root = typeof exports !== "undefined" && exports !== null ? exports : window;
4
4
 
5
5
  require('indemma/lib/record/validatable');
6
6
 
7
- describe('model #() validates_associated', function() {
7
+ describe('model ( validates_associated: ... )', function() {
8
8
  return describe('basic usage', function() {
9
9
  var address, model, person;
10
10
 
@@ -26,7 +26,7 @@ describe('model #() validates_associated', function() {
26
26
  person.validators.length = 0;
27
27
  return address.validators.length = 0;
28
28
  });
29
- return describe('#validate', function() {
29
+ return describe('.validate()', function() {
30
30
  return it('should add error to record when fields does not match', function() {
31
31
  var arthur;
32
32
 
@@ -20,7 +20,6 @@ plural = # has_many ## TODO embeds_many
20
20
  build: (data = {}) ->
21
21
  data.parent_resource = @parent_resource
22
22
 
23
-
24
23
  # TODO Setup a before save callback to generate route when there is no id
25
24
  data.route ||= "#{@parent.route}/#{@parent._id}/#{model.pluralize @resource.toString()}" if @parent?
26
25
  throw "associable.has_many: cannot redefine route of association #{@parent_resource}.#{@resource} from #{@route} to #{data.route}" if @route isnt data.route and @route
@@ -54,15 +53,15 @@ subscribers =
54
53
  association_name = @resource.toString()
55
54
 
56
55
  # TODO faster nullifing association check
57
- # TODO only allow nullifying with null
58
- if resource_id == null or resource_id == undefined
56
+ # TODO check if its usefull to only allow disassociating with null
57
+ unless resource_id
59
58
  @dirty = true
60
59
  @owner[association_name] = resource_id
61
60
  return resource_id
62
61
 
63
62
  # TODO Discover and update inverse side of association
64
63
  # associated[@owner.resource.toString()] = @owner
65
- current_resource_id = @owner[association_name]?._id
64
+ current_resource_id = @owner.observed[association_name]?._id
66
65
  if resource_id != current_resource_id
67
66
  # Update association with blank resource that will update
68
67
  resource = model[association_name]
@@ -71,10 +70,13 @@ subscribers =
71
70
  return resource_id
72
71
 
73
72
  # TODO remote find or local find automatically, and implement find_or_initialize_by
74
- associated = resource.find resource_id
75
- associated ||= resource _id: resource_id
73
+ # this code is not needed, since the association loader already loads the associated record when trying to get it
74
+ # associated = resource.find resource_id
75
+ # associated ||= resource _id: resource_id
76
76
 
77
- @owner.observed[association_name] = associated
77
+ # Nullify associated object, so next time user accesses it,
78
+ # association loader loads the new object
79
+ @owner.observed[association_name] = null
78
80
 
79
81
  resource_id
80
82
 
@@ -83,7 +85,7 @@ subscribers =
83
85
  @owner.observed["#{@resource.toString()}_id"] = if associated then associated._id else null
84
86
 
85
87
  modifiers =
86
- # Called before record initialization to create the a lazy loader
88
+ # Called before record initialization to create the a lazy loader
87
89
  # for other records
88
90
  belongs_to:
89
91
  associated_loader: ->
@@ -102,7 +104,7 @@ modifiers =
102
104
  # resource and on retrievability of the resource
103
105
  return associated unless associated?._id? or associated_id
104
106
 
105
- # Retunrs imediatelly for resources on storage
107
+ # Returns imediatelly for resources on storage
106
108
  # TODO make this extenxible
107
109
  return associated if associated?.sustained
108
110
 
@@ -111,12 +113,17 @@ modifiers =
111
113
  console.warn "subscribers.belongs_to.foreign_key: associated factory not found for model: #{association_name}"
112
114
  return associated
113
115
 
116
+ # Search through stored resources to see if it is stored
114
117
  associated = resource.find associated_id || associated._id
115
- associated ||= resource _id: associated_id
116
118
 
117
- resource.storage.store associated._id, associated
118
- associated.reload()
119
+ # Found associated in storage, update this model and return associated
120
+ return @owner.observed[association_name] = associated if associated
121
+
122
+ # Not found associated in storage
123
+ associated ||= resource _id: associated_id # initialize and store a new record
124
+ associated.reload() # fetch resource
119
125
 
126
+ # Store temporary unloaded resource in this model
120
127
  @owner.observed[association_name] = associated
121
128
 
122
129
  configurable: true
@@ -133,9 +140,14 @@ callbacks =
133
140
  association_names = model[@resource].has_many
134
141
  if association_names
135
142
  for association_name in association_names
143
+
144
+ # Instantiate new records for the association attributes
145
+ # TODO DO not support '_attributes' property on instantiating!
146
+ # TODO define setter for attributes
136
147
  associations_attributes = @["#{association_name}_attributes"]
148
+ association = @[model.pluralize association_name]
149
+
137
150
  if associations_attributes and associations_attributes.length
138
- association = @[model.pluralize association_name]
139
151
 
140
152
  unless association
141
153
  message = "has_many.nest_attributes: Association not found for #{association_name}. \n"
@@ -232,9 +244,19 @@ associable =
232
244
  # @resource = model[resource].resource
233
245
 
234
246
  # TODO Remember to clear association proxy when object is destroyed
235
- association_proxy = resource: resource, parent_resource: @resource, parent: @
236
- association_name = model.pluralize resource
237
- @[association_name] = $.extend association_proxy, plural
247
+ association_proxy = resource: resource, parent_resource: @resource, parent: @
248
+ association_name = model.pluralize resource
249
+
250
+ # When deserializing has many associated resources from
251
+ # server, it is common to send as the association without
252
+ # suffix
253
+ association_attributes = @[association_name] || []
254
+ @["#{association_name}_attributes"] ||= []
255
+ @["#{association_name}_attributes"] = @["#{association_name}_attributes"].concat association_attributes if association_attributes.length
256
+
257
+ # Create or Override sent attributes by the association proxy
258
+ @[association_name] = $.extend association_proxy, plural
259
+
238
260
 
239
261
  # Update association attribute
240
262
  @after 'saved', callbacks.has_many.update_association
@@ -273,7 +295,7 @@ associable =
273
295
  # TODO see why this code is here, since we have the owner key
274
296
  association_proxy[@resource.toString()] = @
275
297
 
276
- @["build_#{resource}" ] = $.proxy singular.build , association_proxy
298
+ @["build_#{resource}"] = $.proxy singular.build , association_proxy
277
299
  @["create_#{resource}"] = $.proxy singular.create, association_proxy
278
300
 
279
301
  # TODO copy from active record and better modularization of
@@ -281,19 +303,21 @@ associable =
281
303
  # To prevent association loading request we must nullify the
282
304
  # association when subscribing
283
305
  old_resource_id = @["#{resource}_id"]
306
+ old_dirty = @dirty
284
307
  @["#{resource}_id"] = null
285
308
 
286
309
  @subscribe "#{resource}_id" , $.proxy subscribers.belongs_to.foreign_key, association_proxy
287
310
  @subscribe resource.toString(), $.proxy subscribers.belongs_to.associated_changed, association_proxy
288
311
 
289
312
  # Restore id after loader prevention has passed
290
- @resource_id = old_resource_id
313
+ @["#{resource}_id"] = old_resource_id
314
+ @dirty = old_dirty
291
315
 
292
316
  # Execute relation attributes binding
293
317
  # TODO validate bindings! When @resource._id != @["#{resource}_id"]
294
318
  # TODO write test for this case
295
- if @["#{resource}_id"] and not @[resource]
296
- @publish "#{resource}_id", @["#{resource}_id"]
319
+ # if @["#{resource}_id"] and not @[resource]
320
+ # @publish "#{resource}_id", @["#{resource}_id"]
297
321
 
298
322
  # TODO better organization of this code, probably transforming the
299
323
  # association into a composable object inside this function: @ =
@@ -13,8 +13,13 @@ handlers =
13
13
  persistable =
14
14
  record:
15
15
  after_initialize: ->
16
- # TODO check persistable configuration before attaching handlers
17
- @after 'saved', handlers.store_after_saved
16
+ if @_id
17
+ # TODO remove global model usage
18
+ {storage} = model[@resource.toString()]
19
+ storage.store @_id, @
20
+ else
21
+ # TODO check persistable configuration before attaching handlers
22
+ @after 'saved', handlers.store_after_saved
18
23
 
19
24
  # Extend indemma
20
25
  # TODO use stampit to extend record and model
@@ -7,6 +7,7 @@ queryable =
7
7
  # FIXME don't let everyone use the same storage instance! or let it?
8
8
  storage: storable()
9
9
  find: (key) ->
10
+ throw new TypeError "InvalidFind: resource.find was called with a falsey value" unless key
10
11
  @storage.store key
11
12
  all: ->
12
13
  @storage.values()
@@ -24,6 +24,32 @@ resource = stampit
24
24
 
25
25
  @
26
26
 
27
+ # TODO Think of a better name, and move to a composable stampit item
28
+ descriptors =
29
+ route:
30
+ get: ->
31
+ # TODO use resource object on associations!
32
+ @resource = name: @resource if typeof @resource == 'string'
33
+
34
+ route = '/'
35
+ route += "#{@parent.route}/#{@parent._id}/" if @parent?
36
+ route += @resource.scope + '/' if @resource.scope?
37
+
38
+ route += if @resource.singular then @resource.name else model.pluralize @resource.name
39
+
40
+ @route = route
41
+
42
+ configurable: true
43
+ # set: (value) -> @initial_route = value
44
+
45
+ # TODO Deprecated! Remove on 15/02/2014
46
+ # parent_id:
47
+ # get: -> @[@parent_resource]._id if @[@parent_resource]
48
+ # set: -> console.error 'Warning changing associations throught parent_id not allowed for security and style guide purposes' # TODO
49
+ # configurable: true
50
+ # enumerable: true
51
+
52
+ # TODO Think of a better name, and move to a composable stampit item
27
53
  resourceable =
28
54
  pluralize: (word, count, plural) ->
29
55
  throw new TypeError "Invalid string passed to pluralize '#{word}'" unless word and word.length
@@ -41,36 +67,13 @@ resourceable =
41
67
  else
42
68
  word
43
69
 
44
- # TODO move to resourceable method
45
- route:
46
- get: ->
47
- return @initial_route if @initial_route?
48
-
49
- # TODO use resource object on associations!
50
- @resource = name: @resource if typeof @resource == 'string'
51
-
52
- route = '/'
53
- route += "#{@parent.route}/#{@parent._id}/" if @parent?
54
- route += @resource.scope + '/' if @resource.scope?
55
-
56
- route += if @resource.singular then @resource.name else model.pluralize @resource.name
57
- @initial_route = route
58
-
59
- route
60
-
61
- set: (value) -> @initial_route = value
62
-
63
- parent_id:
64
- get: -> @[@parent_resource]._id if @[@parent_resource]
65
- set: -> console.error 'Warning changing associations throught parent_id not allowed for security and style guide purposes' # TODO
66
-
67
70
  initialize: ->
71
+
72
+ # Deprecated! Remove on 15/02/2014
68
73
  # Set parent attribute and default nested route
69
- if @parent_resource
70
- Object.defineProperty @, "#{@parent_resource}_id",
71
- value: resourceable.parent_id
72
- configurable: true
73
- enumerable: true
74
+ # If you're using the associable plugin, this getter and setter will be overwritten!
75
+ # if @parent_resource
76
+ # Object.defineProperty @, "#{@parent_resource}_id", descriptors.parent_id
74
77
 
75
78
  # Setup resource
76
79
  resource_definition = {}
@@ -86,13 +89,10 @@ resourceable =
86
89
  # TODO remove mentions of @parent_resource and use only resource: {parent: ...}
87
90
  resource_definition.parent = @parent_resource
88
91
 
89
-
90
-
91
-
92
92
  @resource = resource resource_definition
93
93
 
94
94
  # TODO Support route parsing, and change route to /parents/:id/childrens
95
- @route ? Object.defineProperty @, 'route', resourceable.route
95
+ @route ? Object.defineProperty @, 'route', descriptors.route
96
96
 
97
97
 
98
98
  # Extend indemma