【问题标题】:Return value must be of type ?Illuminate\\Database\\Query\\Builder, App\\Models\\ModelName returned返回值必须是 ?Illuminate\\Database\\Query\\Builder 类型,App\\Models\\ModelName 返回
【发布时间】:2021-10-31 18:15:53
【问题描述】:

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

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

为了做到这一点,我在用户模型中使用了一个 mutator 函数:

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

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

但我按照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',
];
}

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

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

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

【问题讨论】:

    标签: php laravel eloquent laravel-8


    【解决方案1】:

    问题是您在函数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 问题。

    【讨论】:

    • 谢谢,这是 IDE 提示的一个愚蠢的错误,我没有过多关注。感谢您提供的额外提示,因为我是 Laravel 开发的新手,这肯定会有所帮助。
    猜你喜欢
    • 2022-12-28
    • 2022-07-05
    • 2014-06-26
    • 1970-01-01
    • 2020-12-05
    • 2018-03-20
    • 2014-07-09
    • 2017-12-21
    相关资源
    最近更新 更多