.create() can't set non-persistent values
If we define a property as non-persistent and then try to create an entity with .create() that sets that property, Quick will throw an error that it doesn't exist.
Any particular reason we shouldn't be able to set non-persistent values when creating an entity?
A non-persistent property is ignored completely by Quick. When using create or fill, Quick only looks at attributes which is the Quick term for properties it knows and cares about.
You could use insert and update flags on the property to prevent writes, if that is what you are after. (https://quick.ortusbooks.com/guide/getting-started/defining-an-entity#insert-and-update) But if this value never comes from the database, you may want to set it before calling create.
The scenario is that we have an attribute which governs whether certain lifecycle events fire. It never comes from the database.
We can't set it before calling create because it's created via the relationship of a related entity, e.g.
user.posts().create({})
What about adding a custom create method for that entity?
public any function create( struct attributes = {}, boolean ignoreNonExistentAttributes = false ) {
var entity = newEntity();
entity.setLifecycleEventVar( arguments.attributes.lifecycleEventVar ?: "default" );
structDelete( arguments.attributes, "lifecycleEventVar" );
entity.fill( arguments.attributes, arguments.ignoreNonExistentAttributes );
return entity.save();
}
Or what I like to think of as a "named constructor":
public any function createWithLifecycle(
required string lifecycleEventVar,
struct attributes = {},
boolean ignoreNonExistentAttributes = false
) {
var entity = newEntity();
entity.setLifecycleEventVar( arguments.lifecycleEventVar );
entity.fill( arguments.attributes, arguments.ignoreNonExistentAttributes );
return entity.save();
}
Would one of those work?
Sure, but why does .create() need to be particular about setting the attributes as it is now? From the standpoint of 'I want to create this entity,' I don't care whether field A or field B is persistent or not; I'm hydrating an entity. It's not a non-existent attribute, it's just not a persistent attribute.
I can come up with a workaround but it's not obvious to me that one should be required.
Hmmm....I'm not sure. fill definitely does a lot more than just call setters. But if that is added and the tests pass I have no problems with it.