返回值的类型必须为?照明\数据库\查询\生成器,返回了App\Models\ModelName

2022-03-27 00:00:00 php laravel laravel-8 eloquent

我正在尝试获得以下响应:

"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
                    } 
    }

而不是:

"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
    }

为此,我在用户模型中使用赋值函数:

public function getCountryIdAttribute(): Builder|null
{
   return Country::where('id', $this->attributes['country_id'])
    ->get()
    ->first();
}

但是,已经在我正确设置其连接的外部数据库中找到了Countries表。

但我创建的国家/地区模型如下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',
];
}

当我尝试获取用户时,收到以下错误:

{
"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
}

我试图尽可能多地解释我的情况。 感谢您的帮助。


解决方案

问题是您在函数getCountryIdAttribute中说它返回Builder | null。当您这样做时

   return Country::where('id', $this->attributes['country_id'])
    ->get()
    ->first();
它将返回Countrynull的实例。要解决问题,您应该将返回类型更新为Country | null

public function getCountryIdAttribute(): Country | null
{
   return Country::where('id', $this->attributes['country_id'])
    ->get()
    ->first();
}

Laravel提供了使用relationships的方法,这将极大地提高您的代码性能。在这种情况下,您可以执行以下操作:

public function country()
{
  return $this->hasOne(Country::class, 'country_id');
}

然后在获取users时,您可以执行以下操作:

$users = User::where(...)->with('country')->get();

这将防止您的代码出现N+1问题。

相关文章