quick icon indicating copy to clipboard operation
quick copied to clipboard

IDEA For Version 5: Allow Filling Relationship on a New Entity

Open homestar9 opened this issue 2 years ago • 0 comments

I've been using Quick now for about 1-2 months and LOVE IT! It's saved me a ton of time compared to when I relied on my own data mapper objects. I have an idea for improving Quick so it can work with more complex apps.

Currently, if you create a new entity, execute fill(), and the data you are attempting to fill contains a sub-entity that is defined in a relationship, you will trigger an error stating that you must first persist the root entity before adding relationships. However, there may be instances where you need to create an instance of a new entity and fill it with data (including nested relationships) before so you can validate it, or execute some behavior, before persisting the whole aggregate chain.

One of the things we learned in the advanced Coldbox HMVC class is that if you have a complex object, it's better to fill it with data and then call validate() on the entity as opposed to just validating the rc scope. This approach becomes even more appropriate as your business logic gets more complex.

Let's say, for example, you have an Invoice entity. That Invoice will need to have one or more LineItem entities in order to pass validation. It would make sense that when creating a new entity via a handler or service, you instantiate the new Invoice, and then fill() it with one or more LineItem entities. Then once, the unpersisted Entity is ready to rock, you validate() it based on the Invoice constraints built into the entity. Assuming the validation passes, you can then persist the root object and then each child relationship object as needed.

Before I started using Quick, I had to handle this type of thing using my Data Mapper layer. The way I would accomplish this task is to first persist the root entity object (Invoice), and then I would look for any child objects. I would then go through each child and create/update as needed while persisting any relationship fields/tables depending on the relationship type. I believe it would be possible to do something similar in Quick if it delays persisting relationships until after all of the root properties have been saved.

Another benefit of this new feature would be that users could create more DRY add or edit forms. For many use cases, a handler shouldn't need to care whether a user is creating a new entity or updating an existing one. It can save a lot of code if both the add() and update() handlers execute a generic save() method that would persist new and existing entities equally.

Here's what I mean:

// Non-DRY Approach
component {

	function add() {
		// instantiate new entity
		// populate entity with rc data
		// validate entity
		// persist entity
		// add relationships
		// validate again with relationships?
	}

	function update() {
		// find or fail existing entity
		// populate entity with rc data
		// validate entity
		// persist entity
	}

}


// DRY Approach
component {

	function add() {
		// instantiate new entity
		save( entity );
	}

	function update() {
		// find or fail existing entity
		save( entity );
	}

	private function save( entity ) {
		// populate entity (including relationships)
		// validate entity
		// persist entity
		// high-fives all around
	}

}

I know the above is a lot, but please let me know if you would like some code examples to show the benefits of being able to fill() an unpersisted entity with relationship data. Please also let me know if you'd like to work on a PR together. I have the basic idea of what needs to be done, but I am not familiar enough with Quick's architecture to know exactly where to make changes and of course what BDD tests need to change.

homestar9 avatar May 18 '22 20:05 homestar9