ember-data-factory-guy 0.1.3 → 0.2.0
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.
- data/Gruntfile.js +1 -0
- data/README.md +45 -26
- data/bower.json +1 -1
- data/dist/ember-data-factory-guy.js +247 -124
- data/dist/ember-data-factory-guy.min.js +1 -1
- data/ember-data-factory-guy.gemspec +1 -1
- data/package.json +2 -7
- data/src/factory_guy.js +56 -24
- data/src/factory_guy_test_mixin.js +26 -7
- data/src/model_definition.js +41 -16
- data/src/sequence.js +2 -3
- data/src/store.js +123 -74
- data/tests/active_model_adapter_factory_test.js +9 -2
- data/tests/factory_guy_test.js +28 -1
- data/tests/fixture_adapter_factory_test.js +15 -15
- data/tests/rest_adapter_factory_test.js +35 -1
- data/vendor/assets/javascripts/ember_data_factory_guy.js +247 -124
- metadata +2 -2
data/Gruntfile.js
CHANGED
@@ -56,6 +56,7 @@ module.exports = function(grunt) {
|
|
56
56
|
grunt.loadNpmTasks('grunt-contrib-concat');
|
57
57
|
grunt.loadNpmTasks('grunt-contrib-uglify');
|
58
58
|
grunt.loadNpmTasks('grunt-contrib-qunit');
|
59
|
+
grunt.loadNpmTasks('grunt-bump');
|
59
60
|
|
60
61
|
grunt.registerTask('default', ['concat', 'uglify']);
|
61
62
|
grunt.registerTask('test', ['concat:dist', 'qunit']);
|
data/README.md
CHANGED
@@ -17,6 +17,13 @@ then:
|
|
17
17
|
$ bundle install
|
18
18
|
```
|
19
19
|
|
20
|
+
then:
|
21
|
+
|
22
|
+
```javascript
|
23
|
+
// require the 'ember_data_factory_guy' javascript file in your test helper
|
24
|
+
//= require ember_data_factory_guy
|
25
|
+
```
|
26
|
+
|
20
27
|
# Using as bower component
|
21
28
|
|
22
29
|
Add as one of your dependencies in bower.json file:
|
@@ -58,13 +65,14 @@ but BEFORE you require your models.
|
|
58
65
|
// Model definitions
|
59
66
|
|
60
67
|
User = DS.Model.extend({
|
61
|
-
name: DS.attr
|
62
|
-
type: DS.attr
|
63
|
-
projects: DS.hasMany
|
68
|
+
name: DS.attr('string'),
|
69
|
+
type: DS.attr('string'),
|
70
|
+
projects: DS.hasMany('project')
|
64
71
|
})
|
65
72
|
|
66
73
|
Project = DS.Model.extend({
|
67
|
-
title:
|
74
|
+
title: DS.attr('string')
|
75
|
+
user: DS.belongsTo('user')
|
68
76
|
})
|
69
77
|
|
70
78
|
////////////////////////////////////////////
|
@@ -77,12 +85,13 @@ but BEFORE you require your models.
|
|
77
85
|
}
|
78
86
|
},
|
79
87
|
|
80
|
-
// default
|
88
|
+
// default 'user' attributes
|
81
89
|
default: {
|
82
90
|
type: 'normal',
|
83
91
|
// use the 'userName' sequence for this attribute
|
84
92
|
name: FactoryGuy.generate('userName')
|
85
93
|
},
|
94
|
+
|
86
95
|
// named 'user' type with custom attributes
|
87
96
|
admin: {
|
88
97
|
type: 'superuser',
|
@@ -91,13 +100,16 @@ but BEFORE you require your models.
|
|
91
100
|
});
|
92
101
|
|
93
102
|
FactoryGuy.define('project', {
|
94
|
-
default: {
|
103
|
+
default: {
|
104
|
+
title: 'Project'
|
105
|
+
}
|
95
106
|
});
|
96
107
|
|
97
108
|
//////////////////////////////////////////////////////////////////
|
98
109
|
// ** Make one fixture at time **
|
99
110
|
// building json with FactoryGuy.build
|
100
111
|
//
|
112
|
+
|
101
113
|
var userJson = FactoryGuy.build('user') // {id: 1, name: 'User1', type: 'normal'}
|
102
114
|
// note the sequence used in the name attribute
|
103
115
|
var user2Json = FactoryGuy.build('user') // {id: 2, name: 'User2', type: 'normal'}
|
@@ -108,26 +120,29 @@ but BEFORE you require your models.
|
|
108
120
|
// ** Make a list of fixtures **
|
109
121
|
// building json with FactoryGuy.buildList
|
110
122
|
//
|
123
|
+
|
111
124
|
var userJson = FactoryGuy.buildList('user',2) // [ {id: 1, name: 'User1', type: 'normal'}, {id: 2, name: 'User2', type: 'normal'} ]
|
112
125
|
|
113
126
|
//////////////////////////////////////////////////////////////////
|
114
|
-
// store.makeFixture method creates model in the store
|
115
|
-
// store.makeList method creates list of models in the store
|
116
127
|
//
|
117
|
-
//
|
118
|
-
//
|
119
|
-
//
|
128
|
+
// with store using => DS.Fixture adapter
|
129
|
+
//
|
130
|
+
// store.makeFixture => creates model in the store and returns json
|
131
|
+
// store.makeList => creates list of models in the store and returns json
|
120
132
|
//
|
121
|
-
store.makeFixture('user'); // user.FIXTURES = {id: 1, name: 'User1', type: 'normal'}
|
122
|
-
store.makeFixture('user', {name: 'bob'}); // user.FIXTURES = {id: 2, name: 'bob', type: 'normal'}
|
123
|
-
store.makeFixture('admin'); // user.FIXTURES = {id: 3, name: 'Admin', type: 'superuser'}
|
124
|
-
store.makeFixture('admin', name: 'My name'); // user.FIXTURES = {id: 4, name: 'My name', type: 'normal'}
|
125
133
|
|
134
|
+
store.makeFixture('user'); // user.FIXTURES = [{id: 1, name: 'User1', type: 'normal'}]
|
135
|
+
store.makeFixture('user', {name: 'bob'}); // user.FIXTURES = [{id: 2, name: 'bob', type: 'normal'}]
|
136
|
+
store.makeFixture('admin'); // user.FIXTURES = [{id: 3, name: 'Admin', type: 'superuser'}]
|
137
|
+
store.makeFixture('admin', name: 'Fred'); // user.FIXTURES = [{id: 4, name: 'Fred', type: 'superuser'}]
|
126
138
|
|
127
|
-
|
128
|
-
store.
|
129
|
-
|
130
|
-
|
139
|
+
|
140
|
+
// Use store.find to get the model instance ( Remember this is the Fixture adapter, if
|
141
|
+
// you use the ActiveModelAdapter or RESTAdapter the record is returned so you don't
|
142
|
+
// have to then go and find it
|
143
|
+
var userJson = store.makeFixture('user');
|
144
|
+
store.find('user', userJson.id).then(function(user) {
|
145
|
+
user.toJSON() ( has all the same key/values as ) userJson;
|
131
146
|
});
|
132
147
|
|
133
148
|
// and to setup associations ...
|
@@ -147,21 +162,24 @@ but BEFORE you require your models.
|
|
147
162
|
});
|
148
163
|
});
|
149
164
|
|
165
|
+
|
150
166
|
//////////////////////////////////////////////////////////////////
|
151
|
-
// store.makeFixture method creates model and adds it to store
|
152
|
-
// store.makeList methods creates list of models and ads each to the store
|
153
167
|
//
|
154
|
-
//
|
168
|
+
// with store using => DS.ActiveModelAdapter/DS.RestAdapter
|
155
169
|
//
|
156
|
-
//
|
157
|
-
//
|
170
|
+
// store.makeFixture => creates model in the store and returns model instance
|
171
|
+
// store.makeList => creates list of models in the store and returns model instance
|
158
172
|
//
|
173
|
+
// *NOTE* since you are now getting a model instances, you can synchronously
|
174
|
+
// start asking for data from the model
|
175
|
+
//
|
176
|
+
|
159
177
|
var user = store.makeFixture('user'); // user.toJSON() = {id: 1, name: 'User1', type: 'normal'}
|
160
178
|
// note that the user name is a sequence
|
161
179
|
var user = store.makeFixture('user'); // user.toJSON() = {id: 2, name: 'User2', type: 'normal'}
|
162
180
|
var user = store.makeFixture('user', {name: 'bob'}); // user.toJSON() = {id: 3, name: 'bob', type: 'normal'}
|
163
181
|
var user = store.makeFixture('admin'); // user.toJSON() = {id: 4, name: 'Admin', type: 'superuser'}
|
164
|
-
var user = store.makeFixture('admin', name: '
|
182
|
+
var user = store.makeFixture('admin', name: 'Fred'); // user.toJSON() = {id: 5, name: 'Fred', type: 'superuser'}
|
165
183
|
|
166
184
|
// and to setup associations ...
|
167
185
|
|
@@ -214,12 +232,13 @@ test("make a user using fixture adapter", function() {
|
|
214
232
|
testHelper.useFixtureAdapter();
|
215
233
|
var json = make('user');
|
216
234
|
equal(User.FIXTURES.length, 1);
|
235
|
+
equal(User.FIXTURES[0], json);
|
217
236
|
});
|
218
237
|
|
219
238
|
// assuming your default adapter is ActiveModelAdapter or RESTAdapter
|
220
239
|
test("make a user using your applications default adapter", function() {
|
221
240
|
var user = make('user');
|
222
|
-
equal(store.all('user').get('content.length'), 1)
|
241
|
+
equal(store.all('user').get('content.length'), 1);
|
223
242
|
equal(user instanceof DS.Model, true);
|
224
243
|
});
|
225
244
|
|
data/bower.json
CHANGED
@@ -1,6 +1,5 @@
|
|
1
1
|
Sequence = function (fn) {
|
2
2
|
var index = 1;
|
3
|
-
var fn = fn;
|
4
3
|
|
5
4
|
this.next = function () {
|
6
5
|
return fn.call(this, index++);
|
@@ -9,12 +8,19 @@ Sequence = function (fn) {
|
|
9
8
|
this.reset = function () {
|
10
9
|
index = 1;
|
11
10
|
}
|
12
|
-
}
|
11
|
+
};
|
13
12
|
|
14
13
|
function MissingSequenceError(message) {
|
15
14
|
this.toString = function() { return message }
|
16
|
-
}
|
15
|
+
};
|
16
|
+
|
17
|
+
/**
|
18
|
+
A ModelDefinition encapsulates a model's definition
|
17
19
|
|
20
|
+
@param model
|
21
|
+
@param config
|
22
|
+
@constructor
|
23
|
+
*/
|
18
24
|
ModelDefinition = function (model, config) {
|
19
25
|
var sequences = {};
|
20
26
|
var defaultAttributes = {};
|
@@ -23,36 +29,50 @@ ModelDefinition = function (model, config) {
|
|
23
29
|
this.model = model;
|
24
30
|
|
25
31
|
/**
|
26
|
-
@param name model name like 'user' or named type like 'admin'
|
27
|
-
@
|
28
|
-
|
32
|
+
@param {String} name model name like 'user' or named type like 'admin'
|
33
|
+
@returns {Boolean} true if name is this definitions model or this definition
|
34
|
+
contains a named model with that name
|
29
35
|
*/
|
30
36
|
this.matchesName = function (name) {
|
31
37
|
return model == name || namedModels[name];
|
32
38
|
}
|
33
39
|
|
40
|
+
// TODO
|
34
41
|
this.merge = function (config) {
|
35
42
|
}
|
36
43
|
|
37
44
|
/**
|
38
|
-
|
39
|
-
|
45
|
+
Call the next method on the named sequence function
|
46
|
+
|
47
|
+
@param {String} sequenceName
|
48
|
+
@returns {String} output of sequence function
|
40
49
|
*/
|
41
50
|
this.generate = function (sequenceName) {
|
42
|
-
|
43
|
-
|
51
|
+
var sequence = sequences[sequenceName];
|
52
|
+
if (!sequence) {
|
53
|
+
throw new MissingSequenceError("Can not find that sequence named [" + sequenceName + "] in '" + model + "' definition")
|
44
54
|
}
|
45
|
-
return
|
55
|
+
return sequence.next();
|
46
56
|
}
|
47
57
|
|
58
|
+
/**
|
59
|
+
Build a fixture by name
|
60
|
+
|
61
|
+
@param {String} name fixture name
|
62
|
+
@param {Object} opts attributes to override
|
63
|
+
@returns {Object} json
|
64
|
+
*/
|
48
65
|
this.build = function (name, opts) {
|
49
66
|
var modelAttributes = namedModels[name] || {};
|
67
|
+
// merge default, modelAttributes and opts to get the rough fixture
|
50
68
|
var fixture = $.extend({}, defaultAttributes, modelAttributes, opts);
|
51
|
-
|
52
|
-
|
53
|
-
|
69
|
+
// convert attributes that are functions to strings
|
70
|
+
for (attribute in fixture) {
|
71
|
+
if (typeof fixture[attribute] == 'function') {
|
72
|
+
fixture[attribute] = fixture[attribute].call(this, fixture);
|
54
73
|
}
|
55
74
|
}
|
75
|
+
// set the id, unless it was already set in opts
|
56
76
|
if (!fixture.id) {
|
57
77
|
fixture.id = modelId++;
|
58
78
|
}
|
@@ -60,12 +80,12 @@ ModelDefinition = function (model, config) {
|
|
60
80
|
}
|
61
81
|
|
62
82
|
/**
|
63
|
-
|
83
|
+
Build a list of fixtures
|
64
84
|
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
85
|
+
@param name model name or named model type
|
86
|
+
@param number of fixtures to build
|
87
|
+
@param opts attribute options
|
88
|
+
@returns array of fixtures
|
69
89
|
*/
|
70
90
|
this.buildList = function (name, number, opts) {
|
71
91
|
var arr = [];
|
@@ -75,8 +95,12 @@ ModelDefinition = function (model, config) {
|
|
75
95
|
return arr;
|
76
96
|
}
|
77
97
|
|
98
|
+
// Set the modelId back to 1, and reset the sequences
|
78
99
|
this.reset = function () {
|
79
100
|
modelId = 1;
|
101
|
+
for (name in sequences) {
|
102
|
+
sequences[name].reset();
|
103
|
+
}
|
80
104
|
}
|
81
105
|
|
82
106
|
var parseDefault = function (object) {
|
@@ -144,12 +168,12 @@ FactoryGuy = {
|
|
144
168
|
|
145
169
|
```
|
146
170
|
|
147
|
-
For the Person model, you can define fixtures like 'dude' or
|
148
|
-
and get default values.
|
171
|
+
For the Person model, you can define named fixtures like 'dude' or
|
172
|
+
just use 'person' and get default values.
|
149
173
|
|
150
174
|
And to get those fixtures you would call them this way:
|
151
175
|
|
152
|
-
FactoryGuy.build('
|
176
|
+
FactoryGuy.build('dude') or FactoryGuy.build('person')
|
153
177
|
|
154
178
|
@param model the model to define
|
155
179
|
@param config your model definition object
|
@@ -162,18 +186,41 @@ FactoryGuy = {
|
|
162
186
|
}
|
163
187
|
},
|
164
188
|
|
189
|
+
/**
|
190
|
+
Used in model definitions to declare use of a sequence. For example:
|
191
|
+
|
192
|
+
```
|
193
|
+
|
194
|
+
FactoryGuy.define('person', {
|
195
|
+
sequences: {
|
196
|
+
personName: function(num) {
|
197
|
+
return 'person #' + num;
|
198
|
+
}
|
199
|
+
},
|
200
|
+
default: {
|
201
|
+
name: FactoryGuy.generate('personName')
|
202
|
+
}
|
203
|
+
});
|
204
|
+
|
205
|
+
```
|
206
|
+
|
207
|
+
@param {String} sequenceName
|
208
|
+
@returns {Function} wrapper function that is called by the model
|
209
|
+
definition containing the sequence
|
210
|
+
*/
|
165
211
|
generate: function (sequenceName) {
|
166
212
|
return function () {
|
167
213
|
return this.generate(sequenceName);
|
168
214
|
}
|
169
215
|
},
|
170
216
|
|
171
|
-
|
172
217
|
/**
|
218
|
+
Given a name like 'person' or 'dude' determine what model this name
|
219
|
+
refers to. In this case it's 'person' for each one.
|
173
220
|
|
174
|
-
@param name fixture name could be model name like '
|
175
|
-
|
176
|
-
@returns model associated with fixture name
|
221
|
+
@param {String} name a fixture name could be model name like 'person'
|
222
|
+
or a named person in model definition like 'dude'
|
223
|
+
@returns {String} model name associated with fixture name
|
177
224
|
*/
|
178
225
|
lookupModelForName: function (name) {
|
179
226
|
for (model in this.modelDefinitions) {
|
@@ -186,9 +233,9 @@ FactoryGuy = {
|
|
186
233
|
|
187
234
|
/**
|
188
235
|
|
189
|
-
@param name fixture name could be model name like '
|
190
|
-
|
191
|
-
@returns definition associated with model
|
236
|
+
@param {String} name a fixture name could be model name like 'person'
|
237
|
+
or a named person in model definition like 'dude'
|
238
|
+
@returns {ModelDefinition} definition associated with model
|
192
239
|
*/
|
193
240
|
lookupDefinitionForName: function (name) {
|
194
241
|
for (model in this.modelDefinitions) {
|
@@ -206,9 +253,9 @@ FactoryGuy = {
|
|
206
253
|
FactoryGuy.build('user') for User model
|
207
254
|
FactoryGuy.build('bob') for User model with bob attributes
|
208
255
|
|
209
|
-
@param name fixture name
|
210
|
-
@param opts options that will override default fixture values
|
211
|
-
@returns {
|
256
|
+
@param {String} name fixture name
|
257
|
+
@param {Object} opts options that will override default fixture values
|
258
|
+
@returns {Object} json fixture
|
212
259
|
*/
|
213
260
|
build: function (name, opts) {
|
214
261
|
var definition = this.lookupDefinitionForName(name);
|
@@ -224,10 +271,10 @@ FactoryGuy = {
|
|
224
271
|
FactoryGuy.buildList('user', 2) for 2 User models
|
225
272
|
FactoryGuy.build('bob', 2) for 2 User model with bob attributes
|
226
273
|
|
227
|
-
@param name fixture name
|
228
|
-
@param number number of fixtures to create
|
229
|
-
@param opts options that will override default fixture values
|
230
|
-
@returns list of fixtures
|
274
|
+
@param {String} name fixture name
|
275
|
+
@param {Number} number number of fixtures to create
|
276
|
+
@param {Object} opts options that will override default fixture values
|
277
|
+
@returns {Array} list of fixtures
|
231
278
|
*/
|
232
279
|
buildList: function (name, number, opts) {
|
233
280
|
var definition = this.lookupDefinitionForName(name);
|
@@ -238,9 +285,11 @@ FactoryGuy = {
|
|
238
285
|
},
|
239
286
|
|
240
287
|
/**
|
288
|
+
TODO: This is kind of problematic right now .. needs work
|
289
|
+
|
241
290
|
Clear model instances from FIXTURES array, and from store cache.
|
242
291
|
Reset the id sequence for the models back to zero.
|
243
|
-
|
292
|
+
*/
|
244
293
|
resetModels: function (store) {
|
245
294
|
var typeMaps = store.typeMaps;
|
246
295
|
for (model in this.modelDefinitions) {
|
@@ -259,9 +308,6 @@ FactoryGuy = {
|
|
259
308
|
// store.unloadAll(typeMaps[model].type);
|
260
309
|
// }
|
261
310
|
// }
|
262
|
-
|
263
|
-
// for (model in this.modelDefinitions) {
|
264
|
-
// this.modelDefinitions[model].reset();
|
265
311
|
}
|
266
312
|
},
|
267
313
|
|
@@ -269,9 +315,9 @@ FactoryGuy = {
|
|
269
315
|
Push fixture to model's FIXTURES array.
|
270
316
|
Used when store's adapter is a DS.FixtureAdapter.
|
271
317
|
|
272
|
-
@param
|
273
|
-
@param fixture the fixture to add
|
274
|
-
@returns json fixture data
|
318
|
+
@param {DS.Model} modelClass
|
319
|
+
@param {Object} fixture the fixture to add
|
320
|
+
@returns {Object} json fixture data
|
275
321
|
*/
|
276
322
|
pushFixture: function (modelClass, fixture) {
|
277
323
|
if (!modelClass['FIXTURES']) {
|
@@ -279,22 +325,34 @@ FactoryGuy = {
|
|
279
325
|
}
|
280
326
|
modelClass['FIXTURES'].push(fixture);
|
281
327
|
return fixture;
|
328
|
+
},
|
329
|
+
|
330
|
+
/**
|
331
|
+
Clears all model definitions
|
332
|
+
*/
|
333
|
+
clear: function (opts) {
|
334
|
+
if (!opts) {
|
335
|
+
this.modelDefinitions = {};
|
336
|
+
return;
|
337
|
+
}
|
282
338
|
}
|
283
339
|
}
|
284
340
|
DS.Store.reopen({
|
285
|
-
|
286
|
-
|
341
|
+
/**
|
342
|
+
@returns {Boolean} true if store's adapter is DS.FixtureAdapter
|
343
|
+
*/
|
344
|
+
usingFixtureAdapter: function () {
|
287
345
|
var adapter = this.adapterFor('application');
|
288
|
-
return adapter instanceof DS.FixtureAdapter
|
346
|
+
return adapter instanceof DS.FixtureAdapter;
|
289
347
|
},
|
290
348
|
|
291
349
|
/**
|
292
|
-
|
293
|
-
|
350
|
+
Make new fixture and save to store. If the store is using FixtureAdapter,
|
351
|
+
will push to FIXTURE array, otherwise will use push method on adapter.
|
294
352
|
|
295
|
-
|
296
|
-
|
297
|
-
|
353
|
+
@param {String} name name of fixture
|
354
|
+
@param {Object} options fixture options
|
355
|
+
@returns {Object|DS.Model} json or record depending on the adapter type
|
298
356
|
*/
|
299
357
|
makeFixture: function (name, options) {
|
300
358
|
var modelName = FactoryGuy.lookupModelForName(name);
|
@@ -307,7 +365,7 @@ DS.Store.reopen({
|
|
307
365
|
} else {
|
308
366
|
var self = this;
|
309
367
|
var model;
|
310
|
-
Em.run(
|
368
|
+
Em.run(function () {
|
311
369
|
model = self.push(modelName, fixture);
|
312
370
|
self.setBelongsToRESTAdapter(modelType, modelName, model);
|
313
371
|
});
|
@@ -316,13 +374,13 @@ DS.Store.reopen({
|
|
316
374
|
},
|
317
375
|
|
318
376
|
/**
|
319
|
-
|
377
|
+
Make a list of Fixtures
|
320
378
|
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
379
|
+
@param {String} name name of fixture
|
380
|
+
@param {Number} number number to create
|
381
|
+
@param {Object} options fixture options
|
382
|
+
@returns {Array} list of json fixtures or records depending on the adapter type
|
383
|
+
*/
|
326
384
|
makeList: function (name, number, options) {
|
327
385
|
var arr = [];
|
328
386
|
for (var i = 0; i < number; i++) {
|
@@ -332,16 +390,16 @@ DS.Store.reopen({
|
|
332
390
|
},
|
333
391
|
|
334
392
|
/**
|
335
|
-
|
336
|
-
|
393
|
+
Set the belongsTo association for FixtureAdapter,
|
394
|
+
with models that have a hasMany association.
|
337
395
|
|
338
|
-
|
339
|
-
|
340
|
-
|
396
|
+
For example if a user hasMany projects, then set the user.id
|
397
|
+
on each project that the user hasMany of, so that the project
|
398
|
+
now has the belongsTo user association setup.
|
341
399
|
|
342
|
-
|
343
|
-
|
344
|
-
|
400
|
+
@param {String} modelType model type like App.User
|
401
|
+
@param {String} modelName model name like 'user'
|
402
|
+
@param {Object} parentFixture parent to assign as belongTo
|
345
403
|
*/
|
346
404
|
setBelongsToFixturesAdapter: function (modelType, modelName, parentFixture) {
|
347
405
|
var store = this;
|
@@ -351,7 +409,7 @@ DS.Store.reopen({
|
|
351
409
|
relationShips.hasMany.forEach(function (relationship) {
|
352
410
|
var hasManyModel = store.modelFor(Em.String.singularize(relationship));
|
353
411
|
if (parentFixture[relationship]) {
|
354
|
-
parentFixture[relationship].forEach(function(id) {
|
412
|
+
parentFixture[relationship].forEach(function (id) {
|
355
413
|
var hasManyfixtures = adapter.fixturesForType(hasManyModel);
|
356
414
|
var fixture = adapter.findFixtureById(hasManyfixtures, id);
|
357
415
|
fixture[modelName] = parentFixture.id;
|
@@ -362,38 +420,59 @@ DS.Store.reopen({
|
|
362
420
|
},
|
363
421
|
|
364
422
|
/**
|
365
|
-
|
366
|
-
|
423
|
+
For the REST type models:
|
424
|
+
|
425
|
+
Set the belongsTo association with a hasMany association
|
367
426
|
|
368
|
-
|
369
|
-
on each project that the user hasMany of, so that the project
|
370
|
-
now has the belongsTo user association setup
|
427
|
+
Set this model in the parent hasMany array this model belongsTo
|
371
428
|
|
372
|
-
|
373
|
-
|
374
|
-
|
429
|
+
For example if a user hasMany projects, then set the user
|
430
|
+
on each project that the user hasMany of, so that the project
|
431
|
+
now has the belongsTo user association setup
|
432
|
+
|
433
|
+
@param {DS.Model} modelType model type like 'User'
|
434
|
+
@param {String} modelName model name like 'user'
|
435
|
+
@param {DS.Model} model
|
375
436
|
*/
|
376
|
-
setBelongsToRESTAdapter: function (modelType, modelName,
|
377
|
-
var
|
437
|
+
setBelongsToRESTAdapter: function (modelType, modelName, model) {
|
438
|
+
var self = this;
|
439
|
+
Ember.get(modelType, 'relationshipsByName').forEach(function (name, relationship) {
|
440
|
+
if (relationship.kind == 'hasMany') {
|
441
|
+
var children = model.get(name) || [];
|
442
|
+
children.forEach(function (child) {
|
443
|
+
child.set(modelName, model)
|
444
|
+
})
|
445
|
+
}
|
378
446
|
|
379
|
-
|
380
|
-
|
381
|
-
|
382
|
-
|
383
|
-
|
384
|
-
child.set(modelName, parent)
|
385
|
-
})
|
447
|
+
if (relationship.kind == 'belongsTo') {
|
448
|
+
var belongsToRecord = model.get(name);
|
449
|
+
if (belongsToRecord) {
|
450
|
+
var hasManyName = self.findHasManyRelationshipName(belongsToRecord, model)
|
451
|
+
belongsToRecord.get(hasManyName).addObject(model);
|
386
452
|
}
|
387
|
-
}
|
388
|
-
}
|
453
|
+
}
|
454
|
+
})
|
455
|
+
},
|
456
|
+
|
457
|
+
findHasManyRelationshipName: function (belongToModel, childModel) {
|
458
|
+
var relationshipName;
|
459
|
+
Ember.get(belongToModel.constructor, 'relationshipsByName').forEach(
|
460
|
+
function (name, relationship) {
|
461
|
+
if (relationship.kind == 'hasMany' &&
|
462
|
+
relationship.type == childModel.constructor) {
|
463
|
+
relationshipName = relationship.key;
|
464
|
+
}
|
465
|
+
}
|
466
|
+
)
|
467
|
+
return relationshipName;
|
389
468
|
},
|
390
469
|
|
391
470
|
/**
|
392
|
-
|
393
|
-
|
471
|
+
Adding a pushPayload for FixtureAdapter, but using the original with
|
472
|
+
other adapters that support pushPayload.
|
394
473
|
|
395
|
-
|
396
|
-
|
474
|
+
@param {String} type
|
475
|
+
@param {Object} payload
|
397
476
|
*/
|
398
477
|
pushPayload: function (type, payload) {
|
399
478
|
if (this.usingFixtureAdapter()) {
|
@@ -409,38 +488,63 @@ DS.Store.reopen({
|
|
409
488
|
DS.FixtureAdapter.reopen({
|
410
489
|
|
411
490
|
/**
|
412
|
-
|
413
|
-
|
414
|
-
|
415
|
-
|
416
|
-
|
417
|
-
|
418
|
-
|
419
|
-
|
420
|
-
|
421
|
-
|
422
|
-
|
491
|
+
Overriding createRecord to add the record created to the
|
492
|
+
hashMany records for all of the records that this record belongsTo.
|
493
|
+
|
494
|
+
For example:
|
495
|
+
|
496
|
+
If models are defined like so:
|
497
|
+
|
498
|
+
User = DS.Model.extend({
|
499
|
+
projects: DS.hasMany('project')
|
500
|
+
})
|
501
|
+
|
502
|
+
Project = DS.Model.extend({
|
503
|
+
user: DS.belongsTo('user')
|
504
|
+
})
|
505
|
+
|
506
|
+
and you create a project record with a user defined:
|
507
|
+
store.createRecord('project', {user: user})
|
508
|
+
|
509
|
+
this method will take the new project created and add it to the user's 'projects'
|
510
|
+
hasMany array.
|
511
|
+
|
512
|
+
And a full code example:
|
513
|
+
|
514
|
+
var userJson = store.makeFixture('user');
|
515
|
+
|
516
|
+
store.find('user', userJson.id).then(function(user) {
|
517
|
+
store.createRecord('project', {user: user}).save()
|
518
|
+
.then( function(project) {
|
519
|
+
// user.get('projects.length') == 1;
|
520
|
+
})
|
521
|
+
})
|
522
|
+
|
523
|
+
@method createRecord
|
524
|
+
@param {DS.Store} store
|
525
|
+
@param {subclass of DS.Model} type
|
526
|
+
@param {DS.Model} record
|
527
|
+
@return {Promise} promise
|
528
|
+
*/
|
529
|
+
createRecord: function (store, type, record) {
|
423
530
|
var promise = this._super(store, type, record);
|
424
531
|
|
425
|
-
|
426
|
-
|
427
|
-
|
428
|
-
|
429
|
-
|
430
|
-
|
431
|
-
|
432
|
-
|
433
|
-
|
434
|
-
|
435
|
-
|
436
|
-
|
437
|
-
|
532
|
+
promise.then(function () {
|
533
|
+
var relationShips = Ember.get(type, 'relationshipNames');
|
534
|
+
if (relationShips.belongsTo) {
|
535
|
+
relationShips.belongsTo.forEach(function (relationship) {
|
536
|
+
var belongsToRecord = record.get(relationship);
|
537
|
+
if (belongsToRecord) {
|
538
|
+
var hasManyName = store.findHasManyRelationshipName(belongsToRecord, record);
|
539
|
+
belongsToRecord.get(hasManyName).addObject(record);
|
540
|
+
}
|
541
|
+
})
|
542
|
+
}
|
543
|
+
});
|
544
|
+
|
438
545
|
return promise;
|
439
546
|
}
|
440
|
-
|
441
547
|
})
|
442
|
-
|
443
|
-
|
444
548
|
FactoryGuyTestMixin = Em.Mixin.create({
|
445
549
|
|
446
550
|
// Pass in the app root, which typically is App.
|
@@ -454,6 +558,13 @@ FactoryGuyTestMixin = Em.Mixin.create({
|
|
454
558
|
this.getStore().adapterFor('application').simulateRemoteResponse = false;
|
455
559
|
},
|
456
560
|
|
561
|
+
/**
|
562
|
+
Proxy to store's find method
|
563
|
+
|
564
|
+
@param {String or subclass of DS.Model} type
|
565
|
+
@param {Object|String|Integer|null} id
|
566
|
+
@return {Promise} promise
|
567
|
+
*/
|
457
568
|
find: function(type, id) {
|
458
569
|
return this.getStore().find(type, id);
|
459
570
|
},
|
@@ -474,6 +585,13 @@ FactoryGuyTestMixin = Em.Mixin.create({
|
|
474
585
|
return this.getStore().push(type, hash);
|
475
586
|
},
|
476
587
|
|
588
|
+
/**
|
589
|
+
Using mockjax to stub an http request.
|
590
|
+
|
591
|
+
@param {String} url request url
|
592
|
+
@param {Object} json response
|
593
|
+
@param {Object} options ajax request options
|
594
|
+
*/
|
477
595
|
stubEndpointForHttpRequest: function (url, json, options) {
|
478
596
|
options = options || {};
|
479
597
|
var request = {
|
@@ -492,21 +610,27 @@ FactoryGuyTestMixin = Em.Mixin.create({
|
|
492
610
|
},
|
493
611
|
|
494
612
|
/**
|
495
|
-
|
496
|
-
|
497
|
-
|
498
|
-
|
613
|
+
Handling ajax POST ( create record ) for a model
|
614
|
+
|
615
|
+
@param {String} name of the fixture ( or model ) to create
|
616
|
+
@param {Object} opts fixture options
|
499
617
|
*/
|
500
618
|
handleCreate: function (name, opts) {
|
501
619
|
var model = FactoryGuy.lookupModelForName(name);
|
502
620
|
this.stubEndpointForHttpRequest(
|
503
621
|
"/" + Em.String.pluralize(model),
|
504
|
-
this.
|
622
|
+
this.buildAjaxCreateResponse(name, opts),
|
505
623
|
{type: 'POST'}
|
506
624
|
)
|
507
625
|
},
|
508
626
|
|
509
|
-
|
627
|
+
/**
|
628
|
+
Build the json used for creating record
|
629
|
+
|
630
|
+
@param {String} name of the fixture ( or model ) to create
|
631
|
+
@param {Object} opts fixture options
|
632
|
+
¬ */
|
633
|
+
buildAjaxCreateResponse: function (name, opts) {
|
510
634
|
var fixture = FactoryGuy.build(name, opts);
|
511
635
|
var model = FactoryGuy.lookupModelForName(name);
|
512
636
|
var hash = {};
|
@@ -529,5 +653,4 @@ FactoryGuyTestMixin = Em.Mixin.create({
|
|
529
653
|
teardown: function () {
|
530
654
|
FactoryGuy.resetModels(this.getStore());
|
531
655
|
}
|
532
|
-
|
533
656
|
})
|