I have a model called Shifts with a belongsToMany relationship to a shift_employee table that acts as a pivot table to record applications for employees to shifts. I also have a scope so that I can return applications with shift objects. Here is part my Shift model:
class Shift extends Model
{
//
use SoftDeletes;
use AppHttpTraitsUsesUuid;
protected $guarded = [];
public function applications()
{
return $this->belongsToMany(Employee::class, 'shift_employee')->as('application')->withTimestamps()->withPivot('shortlisted');
}
public function scopeWithApplications($query)
{
$query->with('applications');
}
}
My shift_employee pivot table is pretty simple and the structure is shown below. I have one extra field to determine if an application has been shortlisted:
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');
});
Below is my API show function for retrieving shift info:
public function show($id)
{
$shift = Shift::where('id', $id)
->with ()
->withApplications()
->with ()
->first();
return response([
'shift' => $shift,
]);
}
This is the response that I’m getting:
"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
}
},
{
}
]
}
What I want to do, is to replace the whole “application” inner object with only the field “shortlisted” from the pivot table so that it looks like this:
"shift": {
"id": "2b91f55b-c0ff-4bdb-abc4-02604ba6a161",
"some_field": "some_value",
"applications": [
{
some_field: "some_value",
shortlisted: 0
}
},
{
}
]
}
How can I do that? Ideally an eloquent call to something like withPivot but that excludes other fields and does not return an object. I couldn’t find it in the docs, but does something like that exist?
Advertisement
Answer
i think that the most straightforward way is to make independent relation based on the pivot table using pivot model:
class ShiftEmployee extends Pivot
{
protected $table='shift_employee';
}
now the new relation in Shift Model:
class Shift extends Model
{
public function shortlistedApplications()
{
return $this->hasMany(ShiftEmployee::class,'shift_id');
}
public function scopeWithShortlistedApplications($query)
{
$query->with('shortlistedApplications:shift_id,shortlisted');
}
}
now this new scope would bring the data you want