I’m trying to have the following response:
"user": { "id": 1, "first_name": "john", "last_name": "doe", "email": "john@mail.com", "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": "omar.fd.du@gmail.com", "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 IlluminateDatabaseEloquentModel; 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.
Advertisement
Answer
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.