Skip to content

Commit 4be0ae9

Browse files
committed
Auto merge of #2137 - Turbo87:relationships, r=locks
mirage: Use relationship system see https://www.ember-cli-mirage.com/docs/data-layer/relationships Until now we've been keeping track of the relationships between the mirage resources manually, but mirage has a built-in relationship system for this that can simplify the code quite a bit when used correctly. This PR is replacing this manual tracking with declarative relationships. r? @locks
2 parents 116d13f + d1210db commit 4be0ae9

File tree

14 files changed

+158
-98
lines changed

14 files changed

+158
-98
lines changed

mirage/factories/crate.js

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,5 @@ export default Factory.extend({
2323
updated_at: '2017-02-24T12:34:56Z',
2424

2525
badges: () => [],
26-
categories: () => [],
27-
keywords: () => [],
28-
versions: () => [],
2926
_extra_downloads: () => [],
30-
_owner_teams: () => [],
31-
_owner_users: () => [],
3227
});

mirage/factories/dependency.js

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,6 @@ import { Factory } from 'ember-cli-mirage';
33
const REQS = ['^0.1.0', '^2.1.3', '0.3.7', '~5.2.12'];
44

55
export default Factory.extend({
6-
// crate_id,
7-
// version_id,
8-
96
default_features: i => i % 4 === 3,
107
features: () => [],
118
kind: i => (i % 3 === 0 ? 'dev' : 'normal'),

mirage/factories/version-download.js

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,12 @@
11
import { Factory } from 'ember-cli-mirage';
22

33
export default Factory.extend({
4-
// version
5-
64
date: '2019-05-21',
75
downloads: i => (((i * 42) % 13) + 4) * 2345,
6+
7+
afterCreate(self) {
8+
if (!self.versionId) {
9+
throw new Error(`Missing \`version\` relationship on \`version-download:${self.date}\``);
10+
}
11+
},
812
});

mirage/factories/version.js

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,19 +11,16 @@ export default Factory.extend({
1111
yanked: false,
1212
license: i => LICENSES[i % LICENSES.length],
1313

14-
dl_path() {
15-
return `/api/v1/crates/${this.crate}/${this.num}/download`;
16-
},
17-
1814
downloads: i => (((i + 13) * 42) % 13) * 1234,
1915

2016
features: () => {},
2117
_authors: () => [],
2218

2319
crate_size: i => (((i + 13) * 42) % 13) * 54321,
2420

25-
afterCreate(version, server) {
26-
let crate = server.schema.crates.find(version.crate);
27-
crate.update({ versions: crate.versions.concat(parseInt(version.id, 10)) });
21+
afterCreate(version) {
22+
if (!version.crateId) {
23+
throw new Error(`Missing \`crate\` relationship on \`version:${version.num}\``);
24+
}
2825
},
2926
});

mirage/models/crate.js

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1-
import { Model } from 'ember-cli-mirage';
1+
import { Model, hasMany } from 'ember-cli-mirage';
22

3-
export default Model.extend({});
3+
export default Model.extend({
4+
categories: hasMany(),
5+
keywords: hasMany(),
6+
teamOwners: hasMany('team'),
7+
versions: hasMany(),
8+
userOwners: hasMany('user'),
9+
});

mirage/models/dependency.js

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1-
import { Model } from 'ember-cli-mirage';
1+
import { Model, belongsTo } from 'ember-cli-mirage';
22

3-
export default Model.extend({});
3+
export default Model.extend({
4+
crate: belongsTo(),
5+
version: belongsTo(),
6+
});

mirage/models/version-download.js

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1-
import { Model } from 'ember-cli-mirage';
1+
import { Model, belongsTo } from 'ember-cli-mirage';
22

3-
export default Model.extend({});
3+
export default Model.extend({
4+
version: belongsTo(),
5+
});

mirage/models/version.js

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1-
import { Model } from 'ember-cli-mirage';
1+
import { Model, belongsTo } from 'ember-cli-mirage';
22

3-
export default Model.extend({});
3+
export default Model.extend({
4+
crate: belongsTo(),
5+
});

mirage/route-handlers/crates.js

Lines changed: 11 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -38,17 +38,11 @@ export function register(server) {
3838
let crate = schema.crates.find(crateId);
3939
if (!crate) return notFound();
4040

41-
let categories = schema.categories.all().filter(category => (crate.categories || []).indexOf(category.id) !== -1);
42-
let keywords = schema.keywords.all().filter(keyword => (crate.keywords || []).indexOf(keyword.id) !== -1);
43-
let versions = schema.versions
44-
.all()
45-
.filter(version => (crate.versions || []).indexOf(parseInt(version.id, 10)) !== -1);
46-
4741
return {
4842
...this.serialize(crate),
49-
...this.serialize(categories),
50-
...this.serialize(keywords),
51-
...this.serialize(versions),
43+
...this.serialize(crate.categories),
44+
...this.serialize(crate.keywords),
45+
...this.serialize(crate.versions),
5246
};
5347
});
5448

@@ -61,7 +55,7 @@ export function register(server) {
6155
let crate = schema.crates.find(crateId);
6256
if (!crate) return notFound();
6357

64-
return schema.versions.where({ crate: crateId }).sort((a, b) => compareIsoDates(b.created_at, a.created_at));
58+
return crate.versions.sort((a, b) => compareIsoDates(b.created_at, a.created_at));
6559
});
6660

6761
server.get('/api/v1/crates/:crate_id/:version_num/authors', (schema, request) => {
@@ -70,7 +64,7 @@ export function register(server) {
7064
if (!crate) return notFound();
7165

7266
let num = request.params.version_num;
73-
let version = schema.versions.findBy({ crate: crateId, num });
67+
let version = schema.versions.findBy({ crateId, num });
7468
if (!version) return { errors: [{ detail: `crate \`${crateId}\` does not have a version \`${num}\`` }] };
7569

7670
return { meta: { names: version._authors }, users: [] };
@@ -82,7 +76,7 @@ export function register(server) {
8276
if (!crate) return notFound();
8377

8478
let num = request.params.version_num;
85-
let version = schema.versions.findBy({ crate: crateId, num });
79+
let version = schema.versions.findBy({ crateId, num });
8680
if (!version) return { errors: [{ detail: `crate \`${crateId}\` does not have a version \`${num}\`` }] };
8781

8882
return schema.dependencies.where({ version_id: version.id });
@@ -94,20 +88,18 @@ export function register(server) {
9488
if (!crate) return notFound();
9589

9690
let versionNum = request.params.version_num;
97-
let version = schema.versions.findBy({ crate: crateId, num: versionNum });
91+
let version = schema.versions.findBy({ crateId, num: versionNum });
9892
if (!version) return { errors: [{ detail: `crate \`${crateId}\` does not have a version \`${versionNum}\`` }] };
9993

100-
return schema.versionDownloads.where({ version: version.id });
94+
return schema.versionDownloads.where({ versionId: version.id });
10195
});
10296

10397
server.get('/api/v1/crates/:crate_id/owner_user', function(schema, request) {
10498
let crateId = request.params.crate_id;
10599
let crate = schema.crates.find(crateId);
106100
if (!crate) return notFound();
107101

108-
let users = schema.users.find(crate._owner_users);
109-
110-
let response = this.serialize(users);
102+
let response = this.serialize(crate.userOwners);
111103

112104
response.users.forEach(user => {
113105
user.kind = 'user';
@@ -121,9 +113,7 @@ export function register(server) {
121113
let crate = schema.crates.find(crateId);
122114
if (!crate) return notFound();
123115

124-
let teams = schema.teams.find(crate._owner_teams);
125-
126-
let response = this.serialize(teams);
116+
let response = this.serialize(crate.teamOwners);
127117

128118
response.teams.forEach(team => {
129119
team.kind = 'team';
@@ -157,9 +147,7 @@ export function register(server) {
157147
let crate = schema.crates.find(crateId);
158148
if (!crate) return notFound();
159149

160-
let versionDownloads = schema.versionDownloads
161-
.all()
162-
.filter(it => crate.versions.indexOf(parseInt(it.version, 10)) !== -1);
150+
let versionDownloads = schema.versionDownloads.all().filter(it => it.version.crateId === crateId);
163151

164152
return withMeta(this.serialize(versionDownloads), { extra_downloads: crate._extra_downloads });
165153
});

mirage/serializers/crate.js

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,4 +30,32 @@ export default BaseSerializer.extend({
3030
versions: `/api/v1/crates/${crate.id}/versions`,
3131
};
3232
},
33+
34+
getHashForResource() {
35+
let [hash, addToIncludes] = BaseSerializer.prototype.getHashForResource.apply(this, arguments);
36+
37+
if (Array.isArray(hash)) {
38+
for (let resource of hash) {
39+
this._adjust(resource);
40+
}
41+
} else {
42+
this._adjust(hash);
43+
}
44+
45+
return [hash, addToIncludes];
46+
},
47+
48+
_adjust(hash) {
49+
hash.categories = hash.category_ids;
50+
delete hash.category_ids;
51+
52+
hash.keywords = hash.keyword_ids;
53+
delete hash.keyword_ids;
54+
55+
hash.versions = hash.version_ids;
56+
delete hash.version_ids;
57+
58+
delete hash.team_owner_ids;
59+
delete hash.user_owner_ids;
60+
},
3361
});
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import BaseSerializer from './application';
2+
3+
export default BaseSerializer.extend({
4+
getHashForResource() {
5+
let [hash, addToIncludes] = BaseSerializer.prototype.getHashForResource.apply(this, arguments);
6+
7+
if (Array.isArray(hash)) {
8+
for (let resource of hash) {
9+
this._adjust(resource);
10+
}
11+
} else {
12+
this._adjust(hash);
13+
}
14+
15+
return [hash, addToIncludes];
16+
},
17+
18+
_adjust(hash) {
19+
hash.version = hash.version_id;
20+
delete hash.version_id;
21+
delete hash.id;
22+
},
23+
});

mirage/serializers/version.js

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import BaseSerializer from './application';
22

33
export default BaseSerializer.extend({
44
attrs: [
5-
'crate',
5+
'crate_id',
66
'created_at',
77
'dl_path',
88
'downloads',
@@ -18,9 +18,29 @@ export default BaseSerializer.extend({
1818

1919
links(version) {
2020
return {
21-
authors: `/api/v1/crates/${version.crate}/${version.num}/authors`,
22-
dependencies: `/api/v1/crates/${version.crate}/${version.num}/dependencies`,
23-
version_downloads: `/api/v1/crates/${version.crate}/${version.num}/downloads`,
21+
authors: `/api/v1/crates/${version.crateId}/${version.num}/authors`,
22+
dependencies: `/api/v1/crates/${version.crateId}/${version.num}/dependencies`,
23+
version_downloads: `/api/v1/crates/${version.crateId}/${version.num}/downloads`,
2424
};
2525
},
26+
27+
getHashForResource() {
28+
let [hash, addToIncludes] = BaseSerializer.prototype.getHashForResource.apply(this, arguments);
29+
30+
if (Array.isArray(hash)) {
31+
for (let resource of hash) {
32+
this._adjust(resource);
33+
}
34+
} else {
35+
this._adjust(hash);
36+
}
37+
38+
return [hash, addToIncludes];
39+
},
40+
41+
_adjust(hash) {
42+
hash.dl_path = `/api/v1/crates/${hash.crate_id}/${hash.num}/download`;
43+
hash.crate = hash.crate_id;
44+
delete hash.crate_id;
45+
},
2646
});

tests/acceptance/crate-test.js

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@ module('Acceptance | crate page', function(hooks) {
1616
assert.expect(0);
1717

1818
this.server.create('crate', { name: 'nanomsg', max_version: '0.6.1' });
19-
this.server.create('version', { crate: 'nanomsg', num: '0.6.0' });
20-
this.server.create('version', { crate: 'nanomsg', num: '0.6.1' });
19+
this.server.create('version', { crateId: 'nanomsg', num: '0.6.0' });
20+
this.server.create('version', { crateId: 'nanomsg', num: '0.6.1' });
2121

2222
await visit('/crates/nanomsg');
2323
percySnapshot(assert);
@@ -29,8 +29,8 @@ module('Acceptance | crate page', function(hooks) {
2929
assert.expect(0);
3030

3131
this.server.create('crate', { name: 'nanomsg', max_version: '0.6.1' });
32-
this.server.create('version', { crate: 'nanomsg', num: '0.6.0' });
33-
this.server.create('version', { crate: 'nanomsg', num: '0.6.1' });
32+
this.server.create('version', { crateId: 'nanomsg', num: '0.6.0' });
33+
this.server.create('version', { crateId: 'nanomsg', num: '0.6.1' });
3434

3535
await visit('/crates/nanomsg/0.6.0');
3636
percySnapshot(assert);
@@ -51,7 +51,7 @@ module('Acceptance | crate page', function(hooks) {
5151

5252
test('visiting a crate page from the front page', async function(assert) {
5353
this.server.create('crate', { name: 'nanomsg', newest_version: '0.6.1' });
54-
this.server.create('version', { crate: 'nanomsg', num: '0.6.1' });
54+
this.server.create('version', { crateId: 'nanomsg', num: '0.6.1' });
5555

5656
await visit('/');
5757
await click('[data-test-just-updated] [data-test-crate-link="0"]');
@@ -65,8 +65,8 @@ module('Acceptance | crate page', function(hooks) {
6565

6666
test('visiting /crates/nanomsg', async function(assert) {
6767
this.server.create('crate', { name: 'nanomsg', max_version: '0.6.1' });
68-
this.server.create('version', { crate: 'nanomsg', num: '0.6.0' });
69-
this.server.create('version', { crate: 'nanomsg', num: '0.6.1' });
68+
this.server.create('version', { crateId: 'nanomsg', num: '0.6.0' });
69+
this.server.create('version', { crateId: 'nanomsg', num: '0.6.1' });
7070

7171
await visit('/crates/nanomsg');
7272

@@ -80,8 +80,8 @@ module('Acceptance | crate page', function(hooks) {
8080

8181
test('visiting /crates/nanomsg/', async function(assert) {
8282
this.server.create('crate', { name: 'nanomsg', max_version: '0.6.1' });
83-
this.server.create('version', { crate: 'nanomsg', num: '0.6.0' });
84-
this.server.create('version', { crate: 'nanomsg', num: '0.6.1' });
83+
this.server.create('version', { crateId: 'nanomsg', num: '0.6.0' });
84+
this.server.create('version', { crateId: 'nanomsg', num: '0.6.1' });
8585

8686
await visit('/crates/nanomsg/');
8787

@@ -95,8 +95,8 @@ module('Acceptance | crate page', function(hooks) {
9595

9696
test('visiting /crates/nanomsg/0.6.0', async function(assert) {
9797
this.server.create('crate', { name: 'nanomsg', max_version: '0.6.1' });
98-
this.server.create('version', { crate: 'nanomsg', num: '0.6.0' });
99-
this.server.create('version', { crate: 'nanomsg', num: '0.6.1' });
98+
this.server.create('version', { crateId: 'nanomsg', num: '0.6.0' });
99+
this.server.create('version', { crateId: 'nanomsg', num: '0.6.1' });
100100

101101
await visit('/crates/nanomsg/0.6.0');
102102

0 commit comments

Comments
 (0)