Recently I had the need to use Mementifier profiles from within a related child entity. In my case, I was using Quick’s single-table inheritance to dynamically assemble the parent, and I wanted different mementos from the related children, based on the parent “type”. The good news is, this can all be handled via Mappers within Mementifier.
I want to share how I did this, in case anyone else ever needs to do something similar.
Super simple example:
Let’s say you have a User
entity, and that user has many Post
entities (has many relationship). In our example, when we call getMemento()
on User
we want the Post
entity to use the userpost
profile.
Now, I’m using Quick in my example here, but if you’re not using Quick, simply substitute the setUpMementifier()
method with whatever method you use when configuring your memento. Pro tip: I like to explicitly define defaultIncludes
rather than specifying “*” so Mementifier doesn’t have to introspect the object every time.
Examples:
// User.cfc (a Quick entity)
private void function setUpMementifier() {
// set up the memento defaults
super.setUpMementifier();
// We want to use a specific profile for each of these posts
// Start by definining the mapper
this.memento.mappers[ "posts" ] = function( _, item ) {
// retrieve the relationship and map to a new array
return this.getPosts().map( function( post ) {
// return a memento using a custom profile here
return post.getMemento( profile = "userpost" );
} );
};
}
Now let’s take things up a notch and pretend that User
has some type of inheritance schema. In this next case, we want to dynamically get a different profile based on the userType
property of the User
. We can solve that with a simple switch()
statement.
private void function setUpMementifier() {
// set up the memento defaults
super.setUpMementifier();
// We want to use a specific profile for each of these posts
// Start by definining the mapper
this.memento.mappers[ "posts" ] = function( _, item ) {
// by default, use the generic memento profile
var profile = "default";
// reassign which profile to use based on the userType
switch( getUserType() ) {
case "administrator":
profile="useradmin";
break;
case "contributor":
profile="usercontributor";
break;
default:
}
// map the posts to a new array
return this.getPosts().map( function( post ) {
// specify the custom profile here
return post.getMemento( profile = profile );
} );
};
}