Even though we discussed that you prefer to make some of Laravel's magic happen, I'll try to make my suggested approche clearer.
The foundation of the solution
Tables structure
cars table
id |
color |
... |
make |
model |
created_at |
overrides table
car_id |
id |
color |
... |
make |
model |
created_at |
Eloquent relationships
class Cars extends Model{
// ...
public function overrides()
{
return $this->hasMany(Overrides::class);
}
public function latestOverride()
{
return $this->hasOne(Overrides::class)->latest();
}
// ...
}
A use case scenario
id |
color |
make |
model |
created_at |
1 |
blue |
ford |
f150 |
now() |
The 1st car row
from now on is immutable, no code will be made to change it.
car_id |
id |
color |
make |
model |
created_at |
First override
is the user changing the color
to red
car_id |
id |
color |
make |
model |
created_at |
1 |
1 |
red |
ford |
f150 |
now() |
Second override
is the user changing the color
to brown
and make
to chevy
car_id |
id |
color |
make |
model |
created_at |
1 |
1 |
red |
ford |
f150 |
TIMESTAMP |
1 |
2 |
brown |
ford |
chevy |
now() |
Execution
Car creation
The creation of the Car
is straight forward Car::create($data)
Overriding
public function storeOverride(StoreOverrideRequest $request ,Car $car){
$latest_override = $car->latestOverride()->first();
// Compare the request using "OR" with Override first (if the car have at least one override).
// The Car also this request may be 'blue'. But the latest override is 'red'.
// So this request count as a new different Override.
// The following logic is applied to all properties
// Stop the check and create at first diff
if($request->color !== $latest_override->color || $request->color !== $car->color){
Override::creat($request->validated());
}
}
Retrieving
public function showCar(Car $car){
return [
'car' => $car,
'latestOverride' => $car->latestOverride()->first(),
];
}
Benefits
- No hidden logic.
- Easy versionning. Your user can save overrides and navigate forward and backward through his history of changes.
- Guaranteed few exchanges with the database.
A column/value override approche will limit you on retrieval. you will be obliged to do something like $car->overrides
and then loop through the Collection
to replace the changes on $car
.
Notes
- Using Eloquent getters to query the latest value from the other model would result in a cumbersome code and a huge amount of fetching queries.
- My point of view is that magic may get too complicated and hurt your code evolution and debugging (remember Doctor Strange causing the universe of madness XD)