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

Posted

技术标签:

【中文标题】控制器不断生成带有错误外键名称的 SQL 查询【英文标题】:Controller keeps generating SQL query with wrong foreign key name 【发布时间】:2019-12-15 05:28:00 【问题描述】:

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

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 listings where listings.user_id = 1 和listingsuser_id is not null order by created_at desc limit 1)"

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

我已经试过了:

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

据我所知,这可以工作,但这会产生以下错误:

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

【问题讨论】:

查看这篇文章以了解您的最后一个错误***.com/questions/47710805/… 如果你这样做auth()->user()->listings()->latest()->get() 是否有效? ->latest() 实际上并不执行查询;它是->orderBy('created_at', 'desc') 的简写,所以此时你有一个Builder 实例而不是Collection @TimLwis 拍摄。我错过了那个小细节。这为我解决了这个问题。非常感谢! 【参考方案1】:

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

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

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

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

【讨论】:

以上是关于控制器不断生成带有错误外键名称的 SQL 查询的主要内容,如果未能解决你的问题,请参考以下文章

Java + Hibernate - 将带有值的查询打印到控制台[重复]

Laravel 查询构建器 - 查询不工作但在 SQL 控制台中工作

创建带有外键错误号的 sql 表:150

在 My SQL 中不断收到外键约束失败消息

SQL 表未生成

此 SQL 查询的解决方案?