【问题标题】:Laravel ManyToMany relationship Is reversing tables namesLaravel 多对多关系正在反转表名
【发布时间】:2020-12-08 16:27:59
【问题描述】:

我需要让帖子接受尽可能多的语言,所以我有两个模型 postlanguage 在后期模型中:

public function languages(){
    return $this->belongsToMany(\App\Models\Language::class);
}

在我的语言模型中:

public function posts()
{
    return $this->belongsToMany(\App\Models\Post::class);
}

迁移后:

  Schema::create('posts', function (Blueprint $table) {
        $table->id();
        $table->string('title');
        $table->text('body');
        $table->boolean('puplished')->default(false);
        $table->bigInteger('user_id')->unsigned();
        $table->foreign('user_id')->references('id')->on('users');
        $table->timestamps();
    });

语言迁移:

Schema::create('languages', function (Blueprint $table) {
        $table->id();
        $table->string('text')->unique();
        $table->string('value');
        $table->timestamps();
    });

我还创建了 post_language_table 迁移来连接帖子和语言:

Schema::create('post_language', function (Blueprint $table) {
        $table->id();
        $table->unsignedInteger('post_id');
        $table->unsignedInteger('language_id');
        $table->timestamps();
    });

在我的控制器中:

$langs = collect(json_decode($request->languages,true))->pluck('id');
    $post = [];
    $post['body'] = $request->body;
    $post['title'] = $request->title;
    $post['user_id'] = 1;
    $new_post = \App\Models\Post::create($post);
    $new_post->languages()->attach($langs);

但是当我尝试向数据库插入新记录时,会显示此错误:

Illuminate\Database\QueryException
SQLSTATE[42S02]: Base table or view not found: 1146 Table 'laravel.language_post' doesn't exist (SQL: 
insert into `language_post` (`language_id`, `post_id`) values (1, 4), (3, 4), (4, 4))

所以问题是由于某种原因交换了表名!

【问题讨论】:

    标签: laravel laravel-models


    【解决方案1】:

    基于模型的数据透视表的 Laravel 约定是 table1_table2,其中 table1 是字母表中第一个模型的小写单数版本,table2 是模型的小写单数版本在字母表中排在最后。所以在你的情况下,pivot 表应该是language_post,因为 L 在 P 之前。

    您可以在迁移中修改数据透视表:

    Schema::create('language_post', ...)
    

    或者在关系上覆盖它:

    Post.php:

    public function languages() {
      return $this->belongsToMany(Language::class, 'post_language');
    }
    

    Language.php

    public function posts() {
      return $this->belongsToMany(Post::class, 'post_language');
    }
    

    传递给belongsToMany 的第二个参数是数据透视表的名称。

    来自文档:

    为了确定关系的中间表的表名,Eloquent 会按字母顺序连接两个相关的模型名。

    https://laravel.com/docs/8.x/eloquent-relationships#many-to-many

    【讨论】:

    • 正是我所需要的!
    猜你喜欢
    • 2016-04-26
    • 2021-11-19
    • 1970-01-01
    • 2016-08-18
    • 2011-04-22
    • 1970-01-01
    • 2020-01-09
    • 2016-12-20
    • 1970-01-01
    相关资源
    最近更新 更多