Reputation: 93
Hi there I am working on a Laravel Project in which I have used polymorphic relation. Here is the polymorphic Model:
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class approval extends Model
{
use HasFactory;
public function approvable()
{
return $this->morphTo();
}
}
I put here the query:
return approval::with('approvable')->get();
When I run query the query I get result something like this:
[
{
"id": 27,
"status": "sent",
"description": "<p>Ok its perfect</p>",
"type": null,
"extra_description": null,
"sender_id": 17,
"receiver_id": 18,
"added_by": null,
"approvable_id": 27,
"approvable_type": "App\\Models\\deviation",
"created_at": "2023-01-04T10:25:21.000000Z",
"updated_at": "2023-01-04T10:25:21.000000Z",
"approvable": {
"id": 27,
"externalId": "deviation_261672825172",
"name": "Deviation 1021",
"type": "external",
"internal_type": null,
"seriousness": "level_2",
"schedule_date": "2023-01-06 09:39:32",
"sent_to_manager": null,
"status": "completed",
"completed_at": "2023-01-04 11:15:30",
"root_cause_status": null,
"root_cause_completed_at": null,
"actions_taken_status": null,
"actions_taken_completed_at": null,
"verification_status": null,
"verification_completed_at": null,
"description": "<p>In publishing and graphic design, Lorem ipsum is a placeholder text commonly used to demonstrate the visual form of a document or a typeface without relying on meaningful content. Lorem ipsum may be used as a placeholder before final copy is available.</p>",
"customer_id": 5,
"manager_id": 17,
"added_by": 18,
"company_id": 2,
"created_at": "2023-01-04T09:39:32.000000Z",
"updated_at": "2023-01-04T11:15:30.000000Z",
"ccp_pc": null,
"schedule_type": "auto",
"close_up_notes": "dsfdsfdsf",
"parent_id": 26,
"repeat_incident": "yes",
"affected_products": null,
"complainer": null,
"sample_received": "yes",
"sending_status": "sent"
}
},
{
"id": 28,
"status": "approved",
"description": "<p>fggfdg</p>",
"type": null,
"extra_description": null,
"sender_id": 17,
"receiver_id": 17,
"added_by": null,
"approvable_id": 19,
"approvable_type": "App\\Models\\checklist_category",
"created_at": "2023-01-07T07:14:10.000000Z",
"updated_at": "2023-01-07T07:14:10.000000Z",
"approvable": {
"id": 19,
"name": "Checklist 1009",
"description": "Checklist 1009",
"type": "audit",
"company_id": 2,
"created_by": 17,
"created_at": "2023-01-07T06:37:59.000000Z",
"updated_at": "2023-01-07T07:14:10.000000Z",
"delete_status": "false",
"status": "approved",
"approved_by": 17,
"status_changed_at": "2023-01-07 07:14:10",
"equipment_id": null
}
}
]
It is basically linked with two models right now
checklist_category
deviation
Now, I do not want here all data from related models. I want here that when the type is checklist_category, then I only want to select('id','name','description') from checklist_category model and when the type is deviation, I want to select('id','name','seriousness') from deviation model.
So how would it be possible in eloquent eager loading?
Upvotes: 0
Views: 309
Reputation: 2462
Here is how i would do it :
->with([
'approvable' => function (MorphTo $morphTo)
{
// Use contrain to select some fields
$morphTo->constrain([
ChecklistCategory::class => function (Builder $query) {
$query->select('id');
},
Deviation::class => function (Builder $query) {
$query->select('other_field');
},
]);
},
])
You can use constrain to customize the query for each type of models, and your case add a select.
you have access to the query builder and you can do everything you need, so you can also add where/whereIn and all sorts of calls
If you also need to get relations for each type of models you can use morphWith :
->with([
'approvable' => function (MorphTo $morphTo)
{
// use morphWith to get a subrelation
// (it's the same as calling ->with() inside the ->constrain callback)
$morphTo->morphWith([
ChecklistCategory::class => [
'subrelation_of_checklist_category:id,name',
'another_one:id,created_at'
],
Deviation::class => [
'subrelation_of_deviation:id,deviation_id',
'another_one:id,created_at'
]
]);
},
])
Upvotes: 1