Ghost/ghost/admin/app/models/member.js
Kevin Ansfield fcb27507d3 🐛 Fixed slow loading and high memory usage of members list screen
refs https://github.com/TryGhost/Team/issues/1423

- problem:
  - all members requests were automatically adding `?include=email_recipients` as the email recipients relationship was set up to be always embedded
  - embedded email_recipient records also embed the whole email record
  - on the members index screen this meant for each of the 50 members loaded on a page we were also loading every email they have ever received resulting in a huge API response
  - this was not a problem previously because the API was ignoring the `include` parameter on the browse endpoint and Admin wasn't formatting the include properly in snake_case
- solution:
  - the only place we need associated email recipients is on the member details screen where they are used to show the email activity feed
  - removing the `{embedded: 'always'}` option for the `member.emailRecipients` association stops `?include=email_recipients` being added automatically to every members request
  - the member details screen explicitly adds `?include=email_recipients` so no further changes are needed
  - activity feed will be changing to use proper event objects in the future and further optimisation can be made
2022-03-15 18:26:24 +00:00

51 lines
1.7 KiB
JavaScript

import Model, {attr, hasMany} from '@ember-data/model';
import ValidationEngine from 'ghost-admin/mixins/validation-engine';
import {inject as service} from '@ember/service';
import {task} from 'ember-concurrency';
export default Model.extend(ValidationEngine, {
validationType: 'member',
name: attr('string'),
email: attr('string'),
note: attr('string'),
status: attr('string'),
createdAtUTC: attr('moment-utc'),
lastSeenAtUTC: attr('moment-utc'),
subscriptions: attr('member-subscription'),
subscribed: attr('boolean', {defaultValue: true}),
comped: attr('boolean', {defaultValue: false}),
geolocation: attr('json-string'),
emailCount: attr('number', {defaultValue: 0}),
emailOpenedCount: attr('number', {defaultValue: 0}),
emailOpenRate: attr('number'),
products: attr('member-product'),
labels: hasMany('label', {embedded: 'always', async: false}),
emailRecipients: hasMany('emailRecipient', {async: true}),
ghostPaths: service(),
ajax: service(),
// remove client-generated labels, which have `id: null`.
// Ember Data won't recognize/update them automatically
// when returned from the server with ids.
// https://github.com/emberjs/data/issues/1829
updateLabels() {
let labels = this.labels;
let oldLabels = labels.filterBy('id', null);
labels.removeObjects(oldLabels);
oldLabels.invoke('deleteRecord');
},
fetchSigninUrl: task(function* () {
let url = this.get('ghostPaths.url').api('members', this.id, 'signin_urls');
let response = yield this.ajax.request(url);
return response.member_signin_urls[0];
}).drop()
});