简体   繁体   English

多对多Laravel 5.3不会覆盖模型的列名

[英]Many to many Laravel 5.3 is not overriding column name for a model

I have this tables: 我有这张桌子:

在此处输入图片说明

And I have this models: 我有这个模型:

Video 
Category

I'm trying to query a many to many relation to get all videos that belongs to one specific category. 我正在尝试查询多对多关系,以获取属于一个特定类别的所有视频。

I have a route domain.dev/category/{category} that points to my CategoryController and his respective view. 我有一个路由domain.dev/category/{category}指向我的CategoryController及其各自的视图。 I'm receiving it through $request . 我通过$request收到它。

I tried to fetch the data from models in the controller (echoing with php) and passing the variable to the view and doing: 我试图从控制器中的模型中获取数据(用php回显)并将变量传递给视图并执行以下操作:

@foreach ($category->videos as $video) {
    {{ $video->title }}
}
@endforeach

But when Laravel executes the query it throws an exception, and it shows the query: 但是,当Laravel执行查询时,它将引发异常,并显示查询:

QueryException in Connection.php line 769:
    SQLSTATE[42S22]: Column not found: 1054 Unknown column 'videos.id' in 'on clause' (SQL: select `videos`.*, `videos_categories`.`category_id` as `pivot_category_id`, `videos_categories`.`video_id` as `pivot_video_id` from `videos` inner join `videos_categories` on `videos`.`id` = `videos_categories`.`video_id` where `videos_categories`.`category_id` is null)

It looks like the videos.id column, was not overriden (since I have NO id field in videos , I used videos_id as you can see in the migrations, and in the models. I've explicitly overriden the keys in the models, also in the relations. 它看起来像videos.id列,不重写(因为我没有id在现场videos中,我使用videos_id ,你可以在迁移看见,在模型中,我已经明确地重写钥匙放在了车型,还在关系中。

I didn't knew that was a common practice to use alphabetical order for the pivot tables... And my pivot table is videos_categories and not categories_videos as it should "by convention", so I also overriden the table names in the relations. 我不知道这是一个常见的做法是用字母顺序排列的数据透视表... ...我的数据透视表是videos_categories而不是categories_videos ,因为它应该“按照惯例”,所以我也重写的关系表名。

I don't know what I'm doing wrong, or why laravel its using videos . 我不知道自己在做什么错,或者不知道为什么要使用videos id So I need some help. id所以我需要一些帮助。 I also tried searching for other Q/A before writing my own but I didn't found any solution. 在编写我自己的文档之前,我还尝试过搜索其他问题,但没有找到任何解决方案。

Here's the CategoryController: 这是CategoryController:

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Category;

class CategoryController extends Controller
{
    /**
     * Shows the Category page
     *
     * @return Response
     */
    public function index(Request $request)
    {
        $category = Category::where('category', $request->category)->first();
        // THINGS I TRIED
        /*
        $videos = $category->videos()->get();

        foreach ($category->videos as $video) {
            echo $video->title;
        }
        */

        return view('category.index', ['category' => $category]);
    }
}

Migrations 移居

<?php

use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class CreateVideosTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('videos', function (Blueprint $table) {
            $table->engine = 'InnoDB';

            $table->increments('video_id')->unique();
            $table->string('title', 255);
            $table->string('embed_code', 255);
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('videos');
    }
}

<?php

use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class CreateCategoriesTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('categories', function (Blueprint $table) {
            $table->engine = 'InnoDB';

            $table->increments('category_id')->unique();
            $table->string('category', 45);
            $table->string('thumbnail');
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('categories');
    }
}

Migrations for pivot tables 数据透视表的迁移

<?php

use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class CreateVideosCategoriesTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('videos_categories', function (Blueprint $table) {
            $table->engine = 'InnoDB';

            $table->integer('video_id')->unsigned()->nullable();
            $table->integer('category_id')->unsigned()->nullable();

            $table->foreign('video_id')
                ->references('video_id')
                ->on('videos')
                ->onUpdate('cascade')
                ->onDelete('cascade');

            $table->foreign('category_id')
                ->references('category_id')
                ->on('categories')
                ->onUpdate('cascade')
                ->onDelete('cascade');
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::table('videos_categories', function (Blueprint $table) {
            $table->dropForeign(['video_id', 'category_id']);
            $table->dropColumn('video_id');
            $table->dropColumn('category_id');
        });
        Schema::dropIfExists('videos_categories');
    }
}

Models 楷模

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Video extends Model
{
    protected $table = 'videos';
    protected $primarykey = 'video_id';

    public function categories() {
        return $this->belongsToMany('App\Category', 'videos_categories', 'video_id', 'category_id');
    }
    public function tags() {
        return $this->belongsToMany('App\Tag', 'videos_tags', 'video_id', 'tag_id');
    }
}

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Category extends Model
{
    protected $table = 'categories';
    protected $primarykey = 'category_id';
    public $timestamps = false;

    public function videos()
    {
        return $this->belongsToMany('App\Video', 'videos_categories', 'category_id', 'video_id');
    }
}

The property has to be $primaryKey and not $primarykey in your models. 在您的模型中,该属性必须是$primaryKey而不是$primarykey $primaryKey

By the way, there is a reason why the default value is id and not model_id , it is because it is a standard way of naming your columns, and I would advice not to go against such conventions without a good reason, for the reason you're facing but also because it will ease eventual collaboration with another developer. 顺便说一句,默认值是id而不是model_id是有原因的,这是因为这是命名列的标准方式,我建议不要在没有充分理由的情况下违背此类约定,因为您面临的挑战,还因为它可以简化与其他开发人员的最终协作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM