Hi,
I use CakePHP’s entities as domain models mostly, where I keep the business rules. For those rules to apply correctly, it is important that the object is in a valid state, ie. `status` must be a `InvoiceStatus` enum. The way it is, I must pass an array of values when I instantiate the object:
new Invoice([ 'status' => 'notWhatIexpected' ]);
Invoice is created with an invalid property.
Same applies to `LineItem`, which belongs to `Invoice`. An Invoice with 0 line items makes little sense. How can I catch this? I was thinking about a static creation method, but what is the CakePHP way?
Copilot’s suggestion is to check all values manually before instantiating the invoice, but this doesn’t seem right. Because the validity of the Invoice model is a kind of business rule in itself (“An invoice status can be draft or final”). Therefore I want to encapsulate this logic in the Invoice model.
Regards
What you are looking for is Application Rules
Those are applied when you try to save an entity (and maybe associated entities as well)
As the docs say
rules focus on comparing data against the existing state of your application and/or network.
So your entity state can/must be wrong as it needs to hold the wrong state, but the check logic is being done by the table instance.
If application rules don’t pass the saving process fails.
What you expect is, that validation happens the moment an entity gets state injected into it, which is not what Cake is built upon.
Entities are dumb objects which just repesent state (or desired state) in a row/in the db
Table objects do the logic and validation.
1 Like
Thanks for the link, I wasn’t aware of that part of the docs. Shouldn’t business rules / invariants be framework agnostic? There’s a lot of CakePHP specific code in those rule checks.
Interesting. I thought it was the other way round, table classes being just “dumb” persistence models (hence the Table suffix).
Btw. the doc also states:
entities represent individual rows or domain objects in your application
Well then its up to what you define as domain objects 
That said: If you really want it validated upon creating/patching, then use normal validation rules. Afterwards, getErrors() will give you the issues if any.
I’m trying to go with the standard definition here, which is the model that describes a key aspect of my business domain.
One way would be to create a seperate model in ie. /domain, and then using the data from the entity to run the actual business logic on it. That way, the CakePHP models are not abused for domain matters and the domain stays free of framework logic.