控制器不断生成带有错误外键名称的 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 和listings
。 user_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 - 将带有值的查询打印到控制台[重复]