quick
quick copied to clipboard
[Quick 7.2.0] Calling Getter Method on Relationship Throws Exception
I encountered an issue when calling a getter method on a Quick entity relationship that throws the following exception: Value must be initialized before use.
How to replicate:
- Create a simple entity with a relationship that joins to the same table (simple hierarchy)
component
extends="quick.models.BaseEntity"
accessors="true"
table="category"
{
proprety name="id";
property name="parentId";
// RELATIONSHIPS
function parent() {
return belongsTo( "Category", "parentId", "id" ).withDefault(); // Return a new entity if no match found.
}
}
- Now execute the following code in your handler of choice:
// Works!
prc.category = getInstance( "CategoryQ@cms" ).findOrFail( rc.id );
writeDump( var=prc.category.getParent().isLoaded() );
// Works!
prc.category = getInstance( "CategoryQ@cms" )
.with( "parent" )
.findOrFail( rc.id );
writeDump( var=prc.category.parent().get().isLoaded() );
// Throws Exception!
prc.category = getInstance( "CategoryQ@cms" )
.with( "parent" )
.findOrFail( rc.id );
writeDump( var=prc.category.getParent().isLoaded() ); // Value must be initialized before use.
If you initialize the Quick entity and eager load the relationship using the with()
statement. If the relationship returns null (or a new entity because of withDefault()
and then get the relationship using the get[relationship]()
method, you will get an exception. However, calling the relationship using [relationship]().get()
still works as expected.
Additional Info:
I opened up FusionReactor to see if I could figure out what was going on. What's interesting is that if the entity has a null/empty value for parentId
, the with( "parent" )
statement never attempts a query. However, I suspect that it still caches the result somewhere so that the getter attempts to retrieve a null from the entity cache.
If you call parent().get()
, Quick executes a query and then returns a new instance of the object.
I suspect the problem has to do with the eagerLoadRelation()
method in QuickBuilder, but I'm not sure how to fix it. I believe it should respect the withDefault()
property and cache the new entity.