我想在样本和假设来源之间创建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'
);
}