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.

Was it helpful?

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
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top