Skip to content

Commit 89a0ebe

Browse files
committed
Merge pull request #37 from pixelhandler/polymorphic-resources
Add support for polymorphic association in a resource
2 parents 7c656ce + 8770603 commit 89a0ebe

38 files changed

+771
-18
lines changed

addon/adapters/application.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,8 @@ export default Ember.Object.extend(Ember.Evented, {
103103
resource = resource.resource;
104104
type = resource.type;
105105
}
106-
let service = this.container.lookup('service:' + pluralize(type));
106+
// use resource's service if in container, otherwise use this service to fetch
107+
let service = this.container.lookup('service:' + pluralize(type)) || this;
107108
url = this.fetchUrl(url);
108109
return service.fetch(url, { method: 'GET' });
109110
},

addon/models/resource.js

Lines changed: 18 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -280,26 +280,27 @@ Resource.reopenClass({
280280
}
281281
let type = instance.get('type');
282282
let msg = (type) ? Ember.String.capitalize(singularize(type)) : 'Resource';
283+
let factory = 'model:' + type;
283284
if (!type) {
284285
Ember.Logger.warn(msg + '#create called, instead you should first use ' + msg + '.extend({type:"entity"})');
285-
}
286-
let factory = 'model:' + type;
287-
if (instance.container) {
288-
factory = instance.container.lookupFactory(factory);
289-
let proto = factory.proto();
290-
factory.eachComputedProperty(function(prop) {
291-
if (proto[prop] && proto[prop]._meta && typeof proto[prop]._meta === 'object') {
292-
if (proto[prop]._meta.kind === 'hasOne') {
293-
setupRelationship.call(instance, prop);
294-
} else if (proto[prop]._meta.kind === 'hasMany') {
295-
setupRelationship.call(instance, prop, Ember.A([]));
296-
}
297-
}
298-
});
299286
} else {
300-
msg += '#create should only be called from a container lookup (relationships not setup) ';
301-
msg += 'use this.container.lookupFactory("' + factory + '").create() instead.';
302-
Ember.Logger.warn(msg);
287+
if (instance.container) {
288+
factory = instance.container.lookupFactory(factory);
289+
let proto = factory.proto();
290+
factory.eachComputedProperty(function(prop) {
291+
if (proto[prop] && proto[prop]._meta && typeof proto[prop]._meta === 'object') {
292+
if (proto[prop]._meta.kind === 'hasOne') {
293+
setupRelationship.call(instance, prop);
294+
} else if (proto[prop]._meta.kind === 'hasMany') {
295+
setupRelationship.call(instance, prop, Ember.A([]));
296+
}
297+
}
298+
});
299+
} else {
300+
msg += '#create should only be called from a container lookup (relationships not setup) ';
301+
msg += 'use this.container.lookupFactory("' + factory + '").create() instead.';
302+
Ember.Logger.warn(msg);
303+
}
303304
}
304305
return instance;
305306
}

fixtures/api/pictures.json

Lines changed: 206 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,206 @@
1+
{
2+
"data": [
3+
{
4+
"id": "1",
5+
"type": "pictures",
6+
"links": {
7+
"self": "http://api.pixelhandler.com/api/v1/pictures/1"
8+
},
9+
"attributes": {
10+
"name": "box of chocolates"
11+
},
12+
"relationships": {
13+
"imageable": {
14+
"links": {
15+
"self": "http://api.pixelhandler.com/api/v1/pictures/1/relationships/imageable",
16+
"related": "http://api.pixelhandler.com/api/v1/pictures/1/imageable"
17+
},
18+
"data": {
19+
"type": "products",
20+
"id": "3"
21+
}
22+
}
23+
}
24+
},
25+
{
26+
"id": "2",
27+
"type": "pictures",
28+
"links": {
29+
"self": "http://api.pixelhandler.com/api/v1/pictures/2"
30+
},
31+
"attributes": {
32+
"name": "10 foot candy cane"
33+
},
34+
"relationships": {
35+
"imageable": {
36+
"links": {
37+
"self": "http://api.pixelhandler.com/api/v1/pictures/2/relationships/imageable",
38+
"related": "http://api.pixelhandler.com/api/v1/pictures/2/imageable"
39+
},
40+
"data": {
41+
"type": "products",
42+
"id": "2"
43+
}
44+
}
45+
}
46+
},
47+
{
48+
"id": "3",
49+
"type": "pictures",
50+
"links": {
51+
"self": "http://api.pixelhandler.com/api/v1/pictures/3"
52+
},
53+
"attributes": {
54+
"name": "Hot apple fritter"
55+
},
56+
"relationships": {
57+
"imageable": {
58+
"links": {
59+
"self": "http://api.pixelhandler.com/api/v1/pictures/3/relationships/imageable",
60+
"related": "http://api.pixelhandler.com/api/v1/pictures/3/imageable"
61+
},
62+
"data": {
63+
"type": "products",
64+
"id": "1"
65+
}
66+
}
67+
}
68+
},
69+
{
70+
"id": "4",
71+
"type": "pictures",
72+
"links": {
73+
"self": "http://api.pixelhandler.com/api/v1/pictures/4"
74+
},
75+
"attributes": {
76+
"name": "Boston Creme"
77+
},
78+
"relationships": {
79+
"imageable": {
80+
"links": {
81+
"self": "http://api.pixelhandler.com/api/v1/pictures/4/relationships/imageable",
82+
"related": "http://api.pixelhandler.com/api/v1/pictures/4/imageable"
83+
},
84+
"data": {
85+
"type": "products",
86+
"id": "1"
87+
}
88+
}
89+
}
90+
},
91+
{
92+
"id": "5",
93+
"type": "pictures",
94+
"links": {
95+
"self": "http://api.pixelhandler.com/api/v1/pictures/5"
96+
},
97+
"attributes": {
98+
"name": "Bill at EmberConf"
99+
},
100+
"relationships": {
101+
"imageable": {
102+
"links": {
103+
"self": "http://api.pixelhandler.com/api/v1/pictures/5/relationships/imageable",
104+
"related": "http://api.pixelhandler.com/api/v1/pictures/5/imageable"
105+
},
106+
"data": {
107+
"type": "employees",
108+
"id": "1"
109+
}
110+
}
111+
}
112+
}
113+
],
114+
"included": [
115+
{
116+
"id": "3",
117+
"type": "products",
118+
"links": {
119+
"self": "http://api.pixelhandler.com/api/v1/products/3"
120+
},
121+
"attributes": {
122+
"name": "Chocolates"
123+
},
124+
"relationships": {
125+
"pictures": {
126+
"links": {
127+
"self": "http://api.pixelhandler.com/api/v1/products/3/relationships/pictures",
128+
"related": "http://api.pixelhandler.com/api/v1/products/3/pictures"
129+
}
130+
}
131+
}
132+
},
133+
{
134+
"id": "2",
135+
"type": "products",
136+
"links": {
137+
"self": "http://api.pixelhandler.com/api/v1/products/2"
138+
},
139+
"attributes": {
140+
"name": "Candy Canes"
141+
},
142+
"relationships": {
143+
"pictures": {
144+
"links": {
145+
"self": "http://api.pixelhandler.com/api/v1/products/2/relationships/pictures",
146+
"related": "http://api.pixelhandler.com/api/v1/products/2/pictures"
147+
}
148+
}
149+
}
150+
},
151+
{
152+
"id": "1",
153+
"type": "products",
154+
"links": {
155+
"self": "http://api.pixelhandler.com/api/v1/products/1"
156+
},
157+
"attributes": {
158+
"name": "Donuts"
159+
},
160+
"relationships": {
161+
"pictures": {
162+
"links": {
163+
"self": "http://api.pixelhandler.com/api/v1/products/1/relationships/pictures",
164+
"related": "http://api.pixelhandler.com/api/v1/products/1/pictures"
165+
}
166+
}
167+
}
168+
},
169+
{
170+
"id": "1",
171+
"type": "employees",
172+
"links": {
173+
"self": "http://api.pixelhandler.com/api/v1/employees/1"
174+
},
175+
"attributes": {
176+
"name": "Bill Heaton"
177+
},
178+
"relationships": {
179+
"pictures": {
180+
"links": {
181+
"self": "http://api.pixelhandler.com/api/v1/employees/1/relationships/pictures",
182+
"related": "http://api.pixelhandler.com/api/v1/employees/1/pictures"
183+
}
184+
}
185+
}
186+
}
187+
],
188+
"meta": {
189+
"page": {
190+
"total": 7,
191+
"sort": [
192+
{
193+
"field": "id",
194+
"direction": "asc"
195+
}
196+
],
197+
"offset": 0,
198+
"limit": 5
199+
}
200+
},
201+
"links": {
202+
"first": "http://api.pixelhandler.com/api/v1/pictures?include=imageable&page%5Blimit%5D=5&page%5Boffset%5D=0",
203+
"next": "http://api.pixelhandler.com/api/v1/pictures?include=imageable&page%5Blimit%5D=5&page%5Boffset%5D=5",
204+
"last": "http://api.pixelhandler.com/api/v1/pictures?include=imageable&page%5Blimit%5D=5&page%5Boffset%5D=2"
205+
}
206+
}

fixtures/api/pictures/1.json

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
{
2+
"data": {
3+
"id": "1",
4+
"type": "pictures",
5+
"links": {
6+
"self": "http://api.pixelhandler.com/api/v1/pictures/1"
7+
},
8+
"attributes": {
9+
"name": "box of chocolates"
10+
},
11+
"relationships": {
12+
"imageable": {
13+
"links": {
14+
"self": "http://api.pixelhandler.com/api/v1/pictures/1/relationships/imageable",
15+
"related": "http://api.pixelhandler.com/api/v1/pictures/1/imageable"
16+
}
17+
}
18+
}
19+
}
20+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
{
2+
"data": {
3+
"id": "3",
4+
"type": "products",
5+
"links": {
6+
"self": "http://api.pixelhandler.com/api/v1/products/3"
7+
},
8+
"attributes": {
9+
"name": "Chocolates"
10+
},
11+
"relationships": {
12+
"pictures": {
13+
"links": {
14+
"self": "http://api.pixelhandler.com/api/v1/products/3/relationships/pictures",
15+
"related": "http://api.pixelhandler.com/api/v1/products/3/pictures"
16+
}
17+
}
18+
}
19+
}
20+
}

fixtures/api/pictures/5.json

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
{
2+
"data": {
3+
"id": "5",
4+
"type": "pictures",
5+
"links": {
6+
"self": "http://api.pixelhandler.com/api/v1/pictures/5"
7+
},
8+
"attributes": {
9+
"name": "Bill at EmberConf"
10+
},
11+
"relationships": {
12+
"imageable": {
13+
"links": {
14+
"self": "http://api.pixelhandler.com/api/v1/pictures/5/relationships/imageable",
15+
"related": "http://api.pixelhandler.com/api/v1/pictures/5/imageable"
16+
}
17+
}
18+
}
19+
}
20+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
{
2+
"data": {
3+
"id": "1",
4+
"type": "employees",
5+
"links": {
6+
"self": "http://api.pixelhandler.com/api/v1/employees/1"
7+
},
8+
"attributes": {
9+
"name": "Bill Heaton"
10+
},
11+
"relationships": {
12+
"pictures": {
13+
"links": {
14+
"self": "http://api.pixelhandler.com/api/v1/employees/1/relationships/pictures",
15+
"related": "http://api.pixelhandler.com/api/v1/employees/1/pictures"
16+
}
17+
}
18+
}
19+
}
20+
}

0 commit comments

Comments
 (0)