Eloquent - callback when model fetch is complete
Question
I have a model 'Page' which has a one-to-many relation 'PageCustomField' (like the WordPress concept of a custom field).
This custom field model has two fields, key and value. What I would like to do is be able to do something like the following in a Twig template, where page
is the parent Page model, custom
is the collection of custom fields and email
is the key to query custom field relations. The output would be the value
field of the PageCustomField model.
{{ page.custom.email }}
I have achieved this by adding the following to the Page model:
public $custom = array();
public function extractCustomFields()
{
foreach ($this->customFields as $customField) {
$this->custom[$customField->key] = $customField->value;
}
return $this;
}
Called as follows:
$page = Page::where('slug', 'home')->firstOrFail()->extractCustomFields();
What I would prefer would be to have a callback which did this automatically, however, such as in the static boot method. Something like...
public static function boot()
{
parent::boot();
// Extract PageCustomField relations into 'custom' array
static::fetched(function($model) {
$model->extractCustomFields();
});
}
Looking through the Illuminate\Database\Eloquent\Model methods, I couldn't see a callback which would achieve this, but can it be done? I could override the firstOrFail()
method, but would rather not.
Solution
I believe you could use an accessor for this case.
protected $customFields = [
'email' = 'foo@bar.com'
];
public function getCustomAttribute() {
return $this->customFields; // array
//return (object)$this->customFields; // object
}
Call it:
$user = MyClass::find(1);
echo $user->custom['email']; // array
//echo $user->custom->email; // object