我有这张表:
我有这个型号:
Video
Category
我尝试查询多对多关系,以获取属于某个特定类别的所有视频。
我有一条路线domain.dev/category/{category}
指向我的CategoryController
及其各自的观点。我通过$request
收到了它。
我尝试从控制器中的模型中获取数据(使用php回显)并将变量传递给视图并执行:
@foreach ($category->videos as $video) {
{{ $video->title }}
}
@endforeach
但是当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)
看起来videos.id
列未被覆盖(因为我在id
中没有videos
字段,我使用了videos_id
,正如您在迁移中看到的那样,在模型中。我明确地覆盖了模型中的键,也在关系中。
我不知道对数据透视表使用字母顺序是一种常见的做法......我的数据透视表是videos_categories
而不是categories_videos
,因为它应该"按惯例",所以我也覆盖了关系中的表名。
我不知道我做错了什么,或者为什么要使用videos
来解决它。id
所以我需要一些帮助。在编写自己的Q / A之前,我也尝试过搜索其他Q / A,但我没有找到任何解决方案。
这里是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]);
}
}
迁移
<?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');
}
}
透视表的迁移
<?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');
}
}
模型
<?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');
}
}
答案 0 :(得分:2)
您的模型中的属性必须为$primaryKey
而不是$primarykey
。
顺便说一下,有一个原因是默认值是id
而不是model_id
,这是因为它是命名列的标准方法,我建议不要反对这些惯例没有充分的理由,因为你面临的原因,也因为它将减轻与其他开发者的最终合作。