phplaravellaravel-5eloquent

How To Cast Eloquent Pivot Parameters?


I have the following Eloquent Models with relationships:

class Lead extends Model 
{
    public function contacts() 
    {
        return $this->belongsToMany('App\Contact')
                    ->withPivot('is_primary');
    }
}

class Contact extends Model 
{
    public function leads() 
    {
        return $this->belongsToMany('App\Lead')
                    ->withPivot('is_primary');
    }
}

The pivot table contains an additional param (is_primary) that marks a relationship as the primary. Currently, I see returns like this when I query for a contact:

{
    "id": 565,
    "leads": [
        {
            "id": 349,
             "pivot": {
                "contact_id": "565",
                "lead_id": "349",
                "is_primary": "0"
             }
        }
    ]
}

Is there a way to cast the is_primary in that to a boolean? I've tried adding it to the $casts array of both models but that did not change anything.


Solution

  • Since this is an attribute on the pivot table, using the $casts attribute won't work on either the Lead or Contact model.

    One thing you can try, however, is to use a custom Pivot model with the $casts attribute defined. Documentation on custom pivot models is here. Basically, you create a new Pivot model with your customizations, and then update the Lead and the Contact models to use this custom Pivot model instead of the base one.

    First, create your custom Pivot model which extends the base Pivot model:

    <?php namespace App;
    
    use Illuminate\Database\Eloquent\Relations\Pivot;
    
    class PrimaryPivot extends Pivot {
        protected $casts = ['is_primary' => 'boolean'];
    }
    

    Now, override the newPivot() method on the Lead and the Contact models:

    class Lead extends Model {
        public function newPivot(Model $parent, array $attributes, $table, $exists) {
            return new \App\PrimaryPivot($parent, $attributes, $table, $exists);
        }
    }
    
    class Contact extends Model {
        public function newPivot(Model $parent, array $attributes, $table, $exists) {
            return new \App\PrimaryPivot($parent, $attributes, $table, $exists);
        }
    }