I'm trying to have the following response:
"user": {
"id": 1,
"first_name": "john",
"last_name": "doe",
"email": "[email protected]",
"phone_number": "12345678",
"email_verified_at": null,
"created_at": "2021-09-02T08:57:07.000000Z",
"updated_at": "2021-09-02T08:57:07.000000Z",
"country": {
"id": 1,
"name": "UK",
"phone_code": 44
}
}
Instead of:
"user": {
"id": 1,
"first_name": "john",
"last_name": "doe",
"email": "[email protected]",
"phone_number": "12345678",
"email_verified_at": null,
"created_at": "2021-09-02T08:57:07.000000Z",
"updated_at": "2021-09-02T08:57:07.000000Z",
"country_id": 1
}
In order to do that, I am using a mutator function inside the User Model:
public function getCountryIdAttribute(): Builder|null
{
return Country::where('id', $this->attributes['country_id'])
->get()
->first();
}
However, the countries table is already found in an external database which I set up its connection properly.
But I created the Country Model following this Laravel documentation:
use Illuminate\Database\Eloquent\Model;
class Country extends Model
{
/**
* The database connection that should be used by the model.
*
* @var string
*/
protected $connection = 'my second db connection name';
/**
* The table associated with the model.
*
* @var string
*/
protected $table = 'countries';
/**
* The primary key associated with the table.
*
* @var string
*/
protected $primaryKey = 'id';
/**
* The model's default values for attributes.
*
* @var array
*/
protected $attributes = [
'id',
'name',
'phone_code',
];
}
When I am trying to fetch the user I get the following error:
{
"error": [
"App\\Models\\User::getCountryIdAttribute(): Return value must be of type ?
Illuminate\\Database\\Query\\Builder, App\\Models\\Country returned"
],
"message": "Unhandled server exception",
"code": 500
}
I tried to explain my case as much as possible. Thank you for your help.
The problem is that you are saying in the function getCountryIdAttribute it returns Builder | null. When you do
return Country::where('id', $this->attributes['country_id'])
->get()
->first();
It will return an instance of Country or null. To fix your problem you should update your return type to Country | null:
public function getCountryIdAttribute(): Country | null
{
return Country::where('id', $this->attributes['country_id'])
->get()
->first();
}
Laravel provides ways to work with relationships that will greatly improve your code performance. In this case you can do:
public function country()
{
return $this->hasOne(Country::class, 'country_id');
}
Then when fetching the users you can do:
$users = User::where(...)->with('country')->get();
This will prevent your code from having N+1 problems.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With