I’m in the process of converting some of my traditional models into Quick entities. One of the things I am used to being able to do is inject a reference to a parent entity into a child entity during construction.
However, I’m having difficulty doing this efficiently with Quick. I was hoping I could inject the parent into the child at runtime whenever the relationship method is called, however I could not find a way to do that.
My temporary workaround is to create a reference to the parent through a belongsTo()
relationship and then eager load all the data at once. Unfortunately, the parent is being queried a redundant number of times thus causing the infamous N+1 problem. Is there must be a way to only query the parent Media
once and then inject it into each MediaSize
at runtime?
Here’s my simplified workaround setup:
// Media.cfc
component
extends="quick.models.BaseEntity"
hint="I am the parent media entity"
{
// HasMany Relationship
// Media has many MediaSizes.
// Important: We want each MediaSize to have a reference to (this) Media entity.
function mediaSizes() {
return hasMany( "MediaSizeQ", "mediaId" ).with( "media" );
}
}
// MediaSize.cfc
component
extends="quick.models.BaseEntity"
hint="I am a child media size entity"
{
// BelongsTo Relationship (Reference to parent)
// MediaSize belongs to a Media entity
function media() {
return belongsTo( "MediaQ@cms", "mediaId" );
}
}
// Main.cfc Handler
function index( event, rc, prc ) {
prc.media = mediaService
.with( [ "mediaSizes", "mediaSizes.media" ] ) // eager load
.find( 5 );
// Result: 1 Media Entity with 3 MediaSizes
// cbDebugger QueryCount: 12 Yikes!
}