如何投射雄辩的枢轴参数?

Jos*_*sch 19 php laravel eloquent laravel-5

我有以下Eloquent模型与关系:

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');
    }
}
Run Code Online (Sandbox Code Playgroud)

数据透视表包含一个额外的param(is_primary),用于将关系标记为主要关系.目前,当我查询联系人时,我看到这样的返回:

{
    "id": 565,
    "leads": [
        {
            "id": 349,
             "pivot": {
                "contact_id": "565",
                "lead_id": "349",
                "is_primary": "0"
             }
        }
    ]
}
Run Code Online (Sandbox Code Playgroud)

有没有办法将is_primary其转换为布尔值?我已经尝试将它添加到$casts两个模型的数组中,但这并没有改变任何东西.

Jon*_*hon 24

Laravel 5.4.14中,此问题已得到解决.您可以定义自定义透视模型,并告知您的关系在定义时使用此自定义模型.请参阅定义自定义中间表模型标题下的文档.

为此,您需要创建一个类来表示您的数据透视表并让它扩展Illuminate\Database\Eloquent\Relations\Pivot该类.在本课程中,您可以定义您的$casts属性.

<?php

namespace App;

use Illuminate\Database\Eloquent\Relations\Pivot;

class CustomPivot extends Pivot
{
    protected $casts = [
        'is_primary' => 'boolean'
    ];
}
Run Code Online (Sandbox Code Playgroud)

然后,您可以usingBelongsToMany关系上使用该方法告诉Laravel您希望您的数据透视表使用指定的自定义数据透视模型.

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Lead extends Model
{
    public function contacts()
    {
        return $this->belongsToMany('App\Contact')->using('App\CustomPivot');
    }
}
Run Code Online (Sandbox Code Playgroud)

现在,每当您使用时访问您的数据透视表时->pivot,您应该会发现它是您的自定义数据透视表类的一个实例,并且该$casts属性应该受到尊重.


2017年6月1日更新

@cdwyer关于使用通常的sync/ attach/ save方法更新数据透视表的评论中提出的问题预计将在Laravel 5.5中修复,Laravel 5.5将于下个月(2017年7月)发布.

请参阅此错误报告底部的Taylor评论及其提交,并在此处修复此问题.


pat*_*cus 13

由于这是数据透视表的一个属性,因此使用该$casts属性将不适用于LeadContact模型.

但是,您可以尝试使用定义属性的自定义Pivot模型$casts.有关自定义枢轴模型的文档在这里.基本上,你创建一个新的Pivot与您的自定义模型,然后更新LeadContact车型使用这个定制的Pivot,而不是基地之一的模型.

首先,创建Pivot扩展基本Pivot模型的自定义模型:

<?php namespace App;

use Illuminate\Database\Eloquent\Relations\Pivot;

class PrimaryPivot extends Pivot {
    protected $casts = ['is_primary' => 'boolean'];
}
Run Code Online (Sandbox Code Playgroud)

现在,覆盖和模型newPivot()上的方法:LeadContact

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);
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 虽然这个解决方案是正确的,也是目前最好的方法,但它真的让我很困扰。Laravel 总是那么干净,不得不创建一个新模型来投射扩展的数据透视表属性似乎是不可思议的矫枉过正。 (3认同)

Fus*_*ion 5

好消息!泰勒已经修复了这个错误:

https://github.com/laravel/framework/issues/10533

在 Laravel 5.1 或更高版本中,您可以使用点表示法进行枢轴转换:

protected $casts = [
    'id' => 'integer',
    'courses.pivot.course_id' => 'integer',
    'courses.pivot.active' => 'boolean'
]
Run Code Online (Sandbox Code Playgroud)