Skip to content

Instantly share code, notes, and snippets.

@elgordino
Last active July 8, 2018 22:30
Show Gist options
  • Save elgordino/4bc3ce6153f6ce4b6fa2a74c7414ff9a to your computer and use it in GitHub Desktop.
Save elgordino/4bc3ce6153f6ce4b6fa2a74c7414ff9a to your computer and use it in GitHub Desktop.
An idea for adding path prefixes to models

This gist gives an outline of how emberfire could be modified to allow models to express their own path prefix.

When emberfire assembles a ref it will query the class of the record to see if it has a pathPrefix method, if it does the return of that method is prefixed to the ref that will be used.

The pathPrefix method could be expressed in a mixin then applied to the relevent classes.

import FirebaseAdapter from 'emberfire/adapters/firebase';
import Ember from 'ember';
const { get } = Ember;
export default FirebaseAdapter.extend({
/**
* Return a Firebase reference for a given modelName and optional ID.
* Copied from the emberfire adapter and extended to add an optional pathPrefix from a model
*/
_getCollectionRef(typeClass, id) {
let classModel = this.store.modelFor(typeClass.modelName);
let prefix = null;
if (classModel.pathPrefix) {
prefix = classModel.pathPrefix(this);
}
let ref = this._ref;
if (prefix) {
ref = ref.child(prefix);
}
if (typeClass) {
ref = ref.child(this.pathForType(typeClass.modelName));
}
if (id) {
ref = ref.child(id);
}
return ref;
},
/**
* This is _getAbsoluteRef from the emberfire adapter but with the retrieval of _internalModel modified to use Ember.get
* @param {DS.Model} record
* @return {Firebase}
*/
_getAbsoluteRef(record) {
if (get(record, '_internalModel')) {
record = get(record, '_internalModel');
}
let embeddingParent = this.getFirstEmbeddingParent(record);
if (embeddingParent) {
let { record: parent, relationship } = embeddingParent;
const embeddedKey = parent.store.serializerFor(parent.modelName).keyForRelationship(relationship.key);
let recordRef = this._getAbsoluteRef(parent).child(embeddedKey);
if (relationship.kind === 'hasMany') {
recordRef = recordRef.child(record.id);
}
return recordRef;
}
return this._getCollectionRef(record.type, record.id);
},
});
import DS from 'ember-data';
const { Model, attr, belongsTo, hasMany } = DS;
let ExtendedModel = Model.extend({
// Attributes
name: attr('string'),
createdDate: attr('date'),
// Relationships
createdBy: belongsTo('user'),
team: belongsTo('team'),
import TeamOwnedModel from 'lineup-ninja/mixins/team-owned-model';
ExtendedModel.reopenClass(TeamOwnedModel, {});
export default ExtendedModel;
import Ember from 'ember';
const { Mixin, get, assert, getOwner } = Ember;
export default Mixin.create({
pathPrefix(adapter) {
let owner = getOwner(adapter);
let firebaseUser = owner.lookup('service:user/firebase');
let teamId = get(firebaseUser, 'decodedClaims.team');
assert('Model requires user with team in their token', typeof teamId === 'string');
return `team/${teamId}`;
},
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment