控制器不断生成 SQL 具有错误外键名称的查询

Controller keeps generating SQL query with wrong foreign key name

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

id, name, email, password

列表table:

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]: Column not found: 1054 Unknown column 'listings.user_id' in 'where clause' (SQL: select * from listings where listings.user_id = 1 and listings.user_id is not null order by created_at desc limit 1)"

为什么 returns 使用 user_id 作为外键的查询,即使我特意将 'seller_id' 作为外键放在 User.php 模型中?

我试过放:

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

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

"Call to undefined method Illuminate\Database\Eloquent\Relations\HasMany::mapInto()"

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

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

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

另一方面,最初的错误是由于 User 模型的 listings() 函数中缺少 seller_id 引起的。任何关系的外来id都是Laravel根据模型名称猜测的(User翻译成user_id),但是由于你使用的是seller_id,你需要指定在原始关系和逆定义中。您明白了,但快速解释总是有帮助的。