首页 > 解决方案 > Laravel ManyToMany 与单数表名的关系

问题描述

我想在samplesknown_origins之间创建 ManyToMany 关系。
在我的公司中,我们的约定是使用单数表名,因此如 https://laravel.com/docs/8.x/eloquent#table-names中所述,我定义:
迁移

  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('App\SupposedOrigin');
    }
}

class SupposedOrigin extends Model
{
    protected $table = 'v3_supposed_origin';

    public function samples() {
        return $this->belongsToMany('App\Sample');
    }   
}

控制器

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 Ver 15.1 Distrib 10.1.47-MariaDB

标签: laraveleloquent

解决方案


您的问题是您使用的是查询生成器,而不是 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


推荐阅读