英文:
Laravel 8 Eloquent one-to-many relationship data retrieval issue
问题
我一直在关注互联网上关于Eloquent(在Laravel 8中)中一对多关系的教程。它使用Laravel迁移创建了一个包含两个简单表("cars"和"car_models")的简单mySQL数据库。
以下是迁移文件:
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateCarsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('cars', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->integer('founded');
$table->longText('description');
$table->timestamps();
});
Schema::create('car_models', function (Blueprint $table) {
$table->increments('id');
$table->unsignedInteger('car_id');
$table->string('model_name');
$table->timestamps();
$table->foreign('car_id')
->references('id')
->on('cars')
->onDelete('cascade');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('cars');
}
}
以下是"cars"表:
mysql> desc cars;
+-------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------------+--------------+------+-----+---------+----------------+
| id | int unsigned | NO | PRI | NULL | auto_increment |
| name | varchar(255) | NO | | NULL | |
| founded | int | NO | | NULL | |
| description | longtext | NO | | NULL | |
| created_at | timestamp | YES | | NULL | |
| updated_at | timestamp | YES | | NULL | |
+-------------+--------------+------+-----+---------+----------------+
6 rows in set (0.34 sec)
mysql> select * from cars;
+----+------+---------+-------------------------------------+------------+------------+
| id | name | founded | description | created_at | updated_at |
+----+------+---------+-------------------------------------+------------+------------+
| 2 | Audi | 1908 | this is not the description of Audi | NULL | NULL |
+----+------+---------+-------------------------------------+------------+------------+
1 row in set (0.01 sec)
以下是"car_models"表:
mysql> desc car_models;
+------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------+--------------+------+-----+---------+----------------+
| id | int unsigned | NO | PRI | NULL | auto_increment |
| car_id | int unsigned | NO | MUL | NULL | |
| model_name | varchar(255) | NO | | NULL | |
| created_at | timestamp | YES | | NULL | |
| updated_at | timestamp | YES | | NULL | |
+------------+--------------+------+-----+---------+----------------+
5 rows in set (0.00 sec)
mysql> select * from car_models;
+----+--------+------------+------------+------------+
| id | car_id | model_name | created_at | updated_at |
+----+--------+------------+------------+------------+
| 5 | 2 | A1 | NULL | NULL |
| 6 | 2 | A3 | NULL | NULL |
| 7 | 2 | A5 | NULL | NULL |
+----+--------+------------+------------+------------+
3 rows in set (0.00 sec)
这个示例项目的作用是,从"cars"表中提取所有行并将其传递给一个视图。然后,用户可以单击任何品牌名称,项目将在另一个视图上显示该品牌的所有型号。项目中有两个描述数据的模型。
以下是"Car"模型:
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Car extends Model
{
use HasFactory;
protected $table = 'cars';
protected $primaryKey = 'id';
protected $fillable = ['name', 'founded', 'description'];
public function carModels() {
return $this->hasMany(CarModel::class, 'id', 'car_id');
}
}
以下是"CarModel"模型:
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class CarModel extends Model
{
use HasFactory;
protected $table = 'cars';
protected $primaryKey = 'id';
public function car() {
return $this->belongsTo(Car::class);
}
}
当我严格按照教程的步骤进行时,项目会出现1054错误。
SQLSTATE[42S22]: Column not found: 1054 Unknown column 'cars.car_id' in 'where clause'
在"Car"模型的hasMany()中添加了两个可选参数"foreign key"和"local key"后,问题得以解决。然而,生成的网页显示"未找到模型",而应该显示"A1 A3 A5"。
以下是相关的视图:
@extends('layouts.app')
@section('contents')
<div class="m-auto w-4/5 py-24">
<div class="text-center">
<h1 class="text-5xl uppercase bold">{{ $car->name }}</h1>
</div>
<div class="w-5/6 py-10">
<div class="m-auto">
<span class="uppercase text-blue-500 fold-bold text-xs italic">Founded: {{ $car->founded }}</span>
<h2 class="text-gray-700 text-5xl hover:text-gray-500">
<a href="cars/{{ $car->id }}">{{ $car->name }}</a>
</h2>
<p class="text-lg text-gray-700 py-6">{{ $car->description }}</p>
</div>
<ul>
<p class="text-lg text-gray-700 py-3">Models:</p>
@forelse ($car->carModels as $model)
<li class="inline italic text-gray-600 px-1 py-6">
{{ $model['model_name'] }}
</li>
@empty
<p>No models found</p>
@end
<details>
<summary>英文:</summary>
I have been following a tutorial on the Internet about the one-to-many relationships in Eloquent (in Laravel 8). It has a simple mySQL database with two simple tables ("cars" and "car_models") that were created by using Laravel migration.
Here is the migration file:
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateCarsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('cars', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->integer('founded');
$table->longText('description');
$table->timestamps();
});
Schema::create('car_models', function (Blueprint $table) {
$table->increments('id');
$table->unsignedInteger('car_id');
$table->string('model_name');
$table->timestamps();
$table->foreign('car_id')
->references('id')
->on('cars')
->onDelete('cascade');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('cars');
}
}
Here is the "cars" table:
mysql> desc cars;
+-------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------------+--------------+------+-----+---------+----------------+
| id | int unsigned | NO | PRI | NULL | auto_increment |
| name | varchar(255) | NO | | NULL | |
| founded | int | NO | | NULL | |
| description | longtext | NO | | NULL | |
| created_at | timestamp | YES | | NULL | |
| updated_at | timestamp | YES | | NULL | |
+-------------+--------------+------+-----+---------+----------------+
6 rows in set (0.34 sec)
mysql> select * from cars;
+----+------+---------+-------------------------------------+------------+------------+
| id | name | founded | description | created_at | updated_at |
+----+------+---------+-------------------------------------+------------+------------+
| 2 | Audi | 1908 | this is not the description of Audi | NULL | NULL |
+----+------+---------+-------------------------------------+------------+------------+
1 row in set (0.01 sec)
Here is the "car_models" table:
mysql> desc car_models;
+------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------+--------------+------+-----+---------+----------------+
| id | int unsigned | NO | PRI | NULL | auto_increment |
| car_id | int unsigned | NO | MUL | NULL | |
| model_name | varchar(255) | NO | | NULL | |
| created_at | timestamp | YES | | NULL | |
| updated_at | timestamp | YES | | NULL | |
+------------+--------------+------+-----+---------+----------------+
5 rows in set (0.00 sec)
mysql> select * from car_models;
+----+--------+------------+------------+------------+
| id | car_id | model_name | created_at | updated_at |
+----+--------+------------+------------+------------+
| 5 | 2 | A1 | NULL | NULL |
| 6 | 2 | A3 | NULL | NULL |
| 7 | 2 | A5 | NULL | NULL |
+----+--------+------------+------------+------------+
3 rows in set (0.00 sec)
What the sample project does is, all the rows from the "cars" table are pulled and feeds to a view. The user can then click on any of the brand names and the project will display all the models of that brand on another view. There are two models in the project that describe the data.
Here is the "Car" model:
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Car extends Model
{
use HasFactory;
protected $table = 'cars';
protected $primaryKey = 'id';
// public $timestamps = true;
protected $fillable = ['name', 'founded', 'description'];
public function carModels() {
return $this -> hasMany(CarModel::class, 'id', 'car_id');
}
}
Here is the "CarModel" model:
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class CarModel extends Model
{
use HasFactory;
protected $table = 'cars';
protected $primaryKey = 'id';
public function car() {
return $this -> belongsTo(Car::class);
}
}
When I followed the tutorial strictly in the beginning, the project would bork with a 1054 error.
SQLSTATE[42S22]: Column not found: 1054 Unknown column 'cars.car_id' in 'where clause'
That was fixed after I added in the two optional parameters "foreign key" and "local key" to the hasMany() in the "Car" model. However, the resulting webpage says "No models found" when it should display "A1 A3 A5"
[screenshot of output][1]
Here is the relevant view:
@extends('layouts.app')
@section('contents')
<div class="m-auto w-4/5 py-24">
<div class="text-center">
<h1 class="text-5xl uppercase bold">{{ $car -> name }}</h1>
</div>
<div class="w-5/6 py-10">
<div class="m-auto">
<span class="uppercase text-blue-500 fold-bold text-xs italic">Founded: {{ $car -> founded }}</span>
<h2 class="text-gray-700 text-5xl hover:text-gray-500">
<a href="cars/{{ $car -> id }}">{{ $car -> name }}</a>
</h2>
<p class="text-lg text-gray-700 py-6">{{ $car -> description }}</p>
</div>
<ul>
<p class="text-lg text-gray-700 py-3">Models:</p>
@forelse ($car -> carModels as $model)
<li class="inline italic text-gray-600 px-1 py-6">
{{ $model['model_name'] }}
</li>
@empty
<p>No models found</p>
@endforelse
</ul>
<hr class="mt-4 mb-8" />
</div>
</div>
@endsection
The id is correct as dd() returned a 2.
I have been staring at this for a few hours and my brains are now frizzled. A fresh pair of eyes can assist greatly. Thank you very much.
[1]: https://i.stack.imgur.com/ehrzx.png
</details>
# 答案1
**得分**: 0
我找出了问题所在。
在“CarModels”模型中,受保护的 $table 应该是 "car_models",而不是 "cars"。
<details>
<summary>英文:</summary>
Okay, I found out what's wrong.
In the "CarModels" model, the protected $table should be "car_models," not "cars."
</details>
# 答案2
**得分**: 0
你需要更改你的代码为
```php
public function carModels() {
return $this->hasMany(CarModel::class, 'car_id');
}
无需提供列名 id
。
英文:
you need to change your code with
public function carModels() {
return $this->hasMany(CarModel::class,'car_id');
}
no need to give column name id
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论