在 belonsToMany 关系上使用 withPivot 时限制检索的列

我有一个名为 Shifts 的模型,它与 shift_employee 表具有 belongsToMany 关系,该表充当数据透视表来记录员工的轮班申请。我还有一个范围,以便我可以返回带有移位对象的应用程序。这是我的 Shift 模型的一部分:


class Shift extends Model

{

    //

    use SoftDeletes;

    use \App\Http\Traits\UsesUuid;


    protected $guarded = [];


    public function applications()

    {

        return $this->belongsToMany(Employee::class, 'shift_employee')->as('application')->withTimestamps()->withPivot('shortlisted');

    }


...

    public function scopeWithApplications($query)

    {

        $query->with('applications');

    }

...

}

我的 shift_employee 数据透视表非常简单,结构如下所示。我有一个额外的字段来确定应用程序是否已入围:


        Schema::create('shift_employee', function (Blueprint $table) {


        $table->primary(['employee_id', 'shift_id']);

        $table->uuid('employee_id');

        $table->uuid('shift_id');

        $table->boolean('shortlisted')->default(false);

        $table->timestamps();


        $table->foreign('employee_id')

            ->references('id')

            ->on('employees');


        $table->foreign('shift_id')

            ->references('id')

            ->on('shifts')

            ->onDelete('cascade');

        });

下面是我用于检索班次信息的 API show 函数:


public function show($id)

{

    $shift = Shift::where('id', $id)

        ->with...()

        ->withApplications()

        ->with...()

        ->first();


    return response([

        'shift' => $shift,

    ]);

}

这是我得到的回应:


"shift": {

    "id": "2b91f55b-c0ff-4bdb-abc4-02604ba6a161",

    "some_field": "some_value",

    ...

    "applications": [

        {

            some_field: "some_value",

            ...

            application: {

                shift_id: "2b91f55b-c0ff-4bdb-abc4-02604ba6a161",

                employee_id: "some_uuid",

                created_at: ...,

                updated_at: ...,

                shortlisted: 0

            }

        },

        {

        ...

        }

    ]

...

}

我想要做的是用数据透视表中的字段“入围”替换整个“应用程序”内部对象,这样它看起来像这样:

我怎样才能做到这一点?理想情况下,雄辩地调用 withPivot 之类的东西,但不包括其他字段并且不返回对象。我在文档中找不到它,但是否存在类似的东西?


米脂
浏览 140回答 3
3回答

饮歌长啸

我认为最直接的方法是使用数据透视模型基于数据透视表建立独立关系:class ShiftEmployee extends Pivot{    protected $table='shift_employee';} 现在是 Shift 模型中的新关系:class Shift extends Model{    public function shortlistedApplications()    {        return $this->hasMany(ShiftEmployee::class,'shift_id');    } public function scopeWithShortlistedApplications($query)    {        $query->with('shortlistedApplications:shift_id,shortlisted');    }}现在这个新范围将带来你想要的数据

当年话下

我认为你需要的是只加载shortlisted你的员工应用程序的属性scopeWithApllications:public function scopeWithApplications($query){    $query->with('applications.application:id,shortlisted');}这仍然会返回一个Application实例作为关系,但只会加载它的shortlisted属性。然后,在检索之后,您可以映射您的集合,以便将应用程序的属性合并到您的员工(如果这真的很重要)。但就数据短缺而言,这可以解决问题。

呼如林

在您的应用程序模型中使用 withPivot 方法。像这样:public function applications(){return $this->belongsToMany('App\Application')    ->withPivot('shortlisted')    ->withTimestamps();}
打开App,查看更多内容
随时随地看视频慕课网APP