async _onResourceUpdated(type, model) {
        debug('_onResourceUpdated', type);

        const resourceConfig = _.find(this.resourcesConfig, {type: type});

        // NOTE: check if any of the route-related fields were changed and only proceed if so
        const ignoredProperties = [...resourceConfig.modelOptions.exclude, 'updated_at'];
        if (!this._containsRoutingAffectingChanges(model, ignoredProperties)) {
            const cachedResource = this.getByIdAndType(type, model.id);

            if (cachedResource && model._changed && Object.keys(model._changed).includes('updated_at')) {
                DomainEvents.dispatch(URLResourceUpdatedEvent.create(Object.assign(cachedResource.data, {
                    resourceType: cachedResource.config.type,
                    updated_at: model._changed.updated_at
                })));
            }

            debug('skipping _onResourceUpdated because only non-route-related properties changed');
            return false;
        }

        // NOTE: synchronous handling for post and pages so that their URL is available without a delay
        //       for more context and future improvements check https://github.com/TryGhost/Ghost/issues/10360
        if (['posts', 'pages'].includes(type)) {
            // CASE: search for the target resource in the cache
            this.data[type].every((resource) => {
                if (resource.data.id === model.id) {
                    const obj = this._prepareModelSync(model, resourceConfig);

                    resource.update(obj);

                    // CASE: Resource is not owned, try to add it again (data has changed, it could be that somebody will own it now)
                    if (!resource.isReserved()) {
                        this.queue.start({
                            event: 'added',
                            action: 'added:' + model.id,
                            eventData: {
                                id: model.id,
                                type: type
                            }
                        });
                    }

                    // break!
                    return false;
                }

                return true;
            });
        } else {
            const [dbResource] = await this._fetchSingle(resourceConfig, model.id);

            const resource = this.data[type].find(r => (r.data.id === model.id));

            // CASE: cached resource exists, API conditions matched with the data in the db
            if (resource && dbResource) {
                resource.update(dbResource);

                // CASE: pretend it was added
                if (!resource.isReserved()) {
                    this.queue.start({
                        event: 'added',
                        action: 'added:' + dbResource.id,
                        eventData: {
                            id: dbResource.id,
                            type: type
                        }
                    });
                }
            } else if (!resource && dbResource) {
                await this._onResourceAdded(type, model);
            } else if (resource && !dbResource) {
                await this._onResourceRemoved(type, model);
            }
        }
    }
@description Listener for "model updated" event.

CASE:
 - post was fetched on bootstrap
 - that means, the post is already published
 - resource exists, but nobody owns it
 - if the model changes, it can be that somebody will then own the post

CASE:
  - post was fetched on bootstrap
  - that means, the post is already published
  - resource exists and is owned by somebody
  - but the data changed and is maybe no longer owned?
  - e.g. featured:false changes and your filter requires featured posts

@param {ResourceType} type
@param {import('bookshelf').Model} model
@private