Model accessor attribute returning related model

Multi tool use
Model accessor attribute returning related model
I have a model called EquipmentProfile
which has a relationship with EquipmentProfileType
defined like so:
EquipmentProfile
EquipmentProfileType
public function equipmentType()
{
return $this->belongsTo(EquipmentProfileType::class, 'equipment_profile_type_id');
}
I have an accessor defind on EquipmentProfile
to enable me to get a specific value from this relationship:
EquipmentProfile
public function getCategoryAttribute()
{
return $this->equipmentType->name;
}
I am then including category
in my $appends
array so that it is included when I am returning the model as JSON.
category
$appends
This works perfectly, except in my JSON response I am also getting the whole relationship to EquipmentProfileType
too:
EquipmentProfileType
//...more fields above
"category": "Brewing",
"equipment_type": {
"id": 10,
"name": "Brewing",
"created_at": null,
"updated_at": null
}
I only want category
to be returned, not the equipment_type
object too. If I remove category
from my $appends
array then equipment_type
is not included in the response.
category
equipment_type
category
$appends
equipment_type
How do I get category
to be returned without equipment_type
?
category
equipment_type
Edit
My controller calls a method on a repository:
public function store(EquipmentProfileRequest $request)
{
$data = $request->except(['api_token']);
return $this->equipmentProfileRepository->store($data, $request->user());
}
Here is the repository code below:
public function store(array $data, User $user)
{
if (!array_key_exists('name', $data) || $data['name'] == '') {
$data['name'] = 'Equipment Profile';
}
$data['user_id'] = $user->id;
return $this->equipmentProfile->create($data);
}
Note
Even using tinker
gives me the same result:
tinker
Psy Shell v0.9.6 (PHP 7.1.7 — cli) by Justin Hileman
>>> AppModelsEquipmentProfile::first()->toJson()
=> "{... "category":"Brewing","equipment_type":{"id":10,"name":"Brewing","created_at":null,"updated_at":null}}"
@Hussein have added this now.
– James
Jul 3 at 0:12
2 Answers
2
The EquipmentType
model is being included in your JSON output, because the relation is automatically loaded when getCategoryAttribute()
is called.
EquipmentType
getCategoryAttribute()
To hide it, add the relation name to the hidden
array on your model. It will then be filtered out when calling toArray()
and toJson()
.
hidden
toArray()
toJson()
class EquipmentProfile extends Model
{
// ...
protected $hidden = [
'equipmentType'
];
// ...
}
but it shouldn't be visible in first place cz the code is returning only the name
– Hussein
Jul 3 at 0:23
If you read the Laravel source code, when a model is serialized (to array or JSON), it includes all attribute values, and all relations. As I said in my answer, because you loaded the relation in order to access the name, it's then included.
– fubar
Jul 3 at 0:55
@fubar thanks for the explanation. I thought it had to be something like that. I didn't see anything in the docs and didn't think to check the source code. Adding it to the
hidden
array did the trick!– James
Jul 3 at 1:16
hidden
Try using this one below:
$result = $this->equipmentProfile->create($data);
return response()->json($result, 200, array(), JSON_PRETTY_PRINT);
That should remove any extra variables and objects.
By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.
can you add the controller code for this ?
– Hussein
Jul 3 at 0:09