首页 > 解决方案 > 控制器不断生成带有错误外键名称的 SQL 查询

问题描述

我有一个数据库表用户,列表用户表:

id, name, email, password

清单表:

id, title, seller_id

列表迁移:

public function up()
    {
        Schema::create('listings', function (Blueprint $table) {
            $table->bigIncrements('id');
            $table->string('title');
            $table->bigInteger('seller_id')->unsigned();
            $table->timestamps();

            $table->foreign('seller_id')->references('id')->on('users')->onDelete('cascade');
        });
    }

用户型号:

public function listings()
    {
        return $this->hasMany(Listing::class);
    }

上市模式:

public function seller()
    {
        return $this->belongsTo(User::class, 'seller_id', 'id');
    }

上市资源:

namespace App\Http\Resources;

use Illuminate\Http\Resources\Json\JsonResource;

class ListingResource extends JsonResource
{
    /**
     * Transform the resource into an array.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return array
     */
    public function toArray($request)
    {
        return parent::toArray($request);
    }
}

清单控制器:

public function index()
    {
        return ListingResource::collection(auth()->user()->listings()->latest());
    }

我不断收到此错误:

“SQLSTATE [42S22]:未找到列:1054 'where 子句'中的未知列'listings.user_id'(SQL:select * from listingswhere listings. user_id= 1 and listings. user_idis not null order by created_atdesc limit 1)”

即使我在 User.php 模型中专门将“seller_id”作为外键,它为什么会返回带有 user_id 作为外键的查询?

我试图把:

    public function listings()
    {
        return $this->hasMany(Listing::class, 'seller_id');
    }

正如我所读到的,这可以工作,但这会产生以下错误:

“调用未定义的方法 Illuminate\Database\Eloquent\Relations\HasMany::mapInto()”

标签: phpmysqllaravellaravel-5.8

解决方案


虽然错误消息对此不是最清楚的,但本质上发生的是{Resource}::collection($collection);需要 aCollection来运行,但在其生命周期的当前点,您的参数是一个Builder实例。要解决此问题,只需传递 aclosure将您的转换Builder为 a Collection

public function index(){
    return ListingResource::collection(auth()->user()->listings()->latest()->get());
}

->latest()->orderBy('created_at', 'DESC');(或者id,不确定它在内部使用哪个)的简写,但实际上并不执行查询。只需添加->get()将转换Builder为 aCollection并允许此资源工作。

另一方面,原始错误是由于模型上seller_idlistings()功能缺失引起的User。Laravel 根据模型名称(User转换为user_id)猜测任何关系的外部 id,但由于您使用的是seller_id,因此您需要在原始关系和反向定义中指定它。你想通了,但快速解释总是有帮助的。


推荐阅读