具有单数表名的Laravel-ManyToMany关系



我想在样本假设来源之间创建ManyToMany关系
在我公司,我们的惯例是使用单数表名,如中所述https://laravel.com/docs/8.x/eloquent#table-名称,我定义了:
迁移

Schema::create('v3_sample', function (Blueprint $table) {
$table->increments('id');
$table->string('number_canonical', 6)->unique(); // business key
$table->string('name')->nullable();
};
Schema::create('v3_supposed_origin', function (Blueprint $table) {
$table->increments('id');
$table->integer('location_id')->unsigned(); // from other database
$table->string('description');
});
Schema::create('v3_sample_supposed_origin', function (Blueprint $table) {
$table->increments('id');
$table->integer('sample_id')->unsigned();
$table->foreign('sample_id')->references('id')->on('v3_sample')->onDelete('cascade');
$table->integer('supposed_origin_id')->unsigned();
$table->foreign('supposed_origin_id')->references('id')->on('v3_supposed_origin')->onDelete('cascade');
});

型号

class Sample extends Model
{
protected $table = 'v3_sample';
public function supposed_origins() {
dd($this);
return $this->belongsToMany('AppSupposedOrigin');
}
}
class SupposedOrigin extends Model
{
protected $table = 'v3_supposed_origin';
public function samples() {
return $this->belongsToMany('AppSample');
}   
}

控制器

class SampleController extends Controller
{
// […]
public function edit(Request $request, $number_canonical)
{
$sample_record = DB::table('v3_sample')->where('number_canonical', $number_canonical)->first();
$supposed_origins = $sample_record->supposed_origins; 
dd($supposed_origins); // returns ErrorException Undefined property: stdClass::$supposed_origins 

SampleController返回ErrorException Undefined property: stdClass::$supposed_origins

由于我有单数表名,因此不遵循定义为将透视表从单数表名(sample_supposed_origin(转换为复数表名(示例和假定起源,而不是我的示例和假定来源(的规则!

问题:

  • 单数命名是它找不到关系的原因吗
  • 有没有一种方法可以正确地指定它?是否添加透视表模型

其他信息:Laravel Framework 7.28.4,PHP 8.0.3,mariadb版本15.1 Distrib 10.1.47-mariadb

您的问题是使用的是查询生成器,而不是Eloquent查询生成器。

DB::table('v3_sample')->where('number_canonical', $number_canonical)->first()将返回一个表示数据库结果的对象,但它只是一个标准的PHP对象。

您想要:

Sample::query()->where('number_canonical', $number_canonical)->first()

这将返回一个Sample模型,您将可以访问所需的关系。

在您的情况下为$sample_record->supposed_origins

@KurtRiars在他的回答中提到,我将控制器更改为:

public function edit(Request $request, $number_canonical)
{
$sample_record = Sample::query()->where('number_canonical', $number_canonical)->first();
$supposed_origins = $sample_record->supposed_origins;

以前的错误消失了,但我有另一个错误:

SQLSTATE[42S02]: Base table or view not found: 1146 Table dbname.sample_supposed_origin' doesn't exist`

要使我的假设来源,还需要改进我的Sample模型,如下所示:

public function supposed_origins() {
return $this->belongsToMany(
'AppSupposedOrigin',
'v3_sample_supposed_origin',
'sample_id',
'supposed_origin_id'
);
}

最新更新