I have a nice trait to manage such kind of “read only” properties:
<?php
namespace App\Traits;
use Illuminate\Database\Eloquent\Model;
trait PersistentProperties
{
protected $securePersistentProperties = true;
public $persistentProperties = [];
// add properties in a format ['propertyName' => Model]
protected function addPersistentProperties(array $modelProperies)
{
foreach($modelProperies as $property => $model){
if($model instanceof Model){
$this->persistentProperties[$property] = [
'id' => $model->getKey(),
'class' => get_class($model)
];
$this->computedPropertyCache[$property] = $model;
}
}
}
// just in case you need to remove
protected function removePersistentProperty($property)
{
if(!is_array($property)) $property = [$property];
foreach ($property as $prop) {
unset($this->persistentProperties[$prop]);
unset($this->computedPropertyCache[$prop]);
}
}
public function initializePersistentProperties()
{
if($this->securePersistentProperties){
$this->lockPropertyFromSync('persistentProperties');
}
}
public function __get($property)
{
// check if this is a persistent property
$persistentProperty = $this->persistentProperties[$property] ?? null;
if($persistentProperty) {
$model = $this->computedPropertyCache[$property] ?? null;
if(!$model) {
$model = $persistentProperty['class']::find($persistentProperty['id']);
$this->computedPropertyCache[$property] = $model;
}
return $model;
}
return parent::__get($property);
}
}
What it was doing is making given properties cached, defined as component property and read only with a very simple syntax:
use PersistentProperties;
public function mount(Forum $forum)
{
$this->addPersistentProperties(['forum' => $forum]);
}
And after it is possible to use $this->forum
and forum was authorized in the controller and you do not need to think about authorization again. But now I am starting from with the same problem again. If I define updating
function in the trait, then I cannot define it in the component, not very flexible… Somehow version 1 was better in this sense.