Laravel 8 Eloquent一对多关系数据检索问题

huangapple go评论47阅读模式
英文:

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 (&quot;cars&quot; and &quot;car_models&quot;) 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(&#39;car_models&#39;, function (Blueprint $table) {
$table-&gt;increments(&#39;id&#39;);
$table-&gt;unsignedInteger(&#39;car_id&#39;);
$table-&gt;string(&#39;model_name&#39;);
$table-&gt;timestamps();
$table-&gt;foreign(&#39;car_id&#39;)
-&gt;references(&#39;id&#39;)
-&gt;on(&#39;cars&#39;)
-&gt;onDelete(&#39;cascade&#39;);
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists(&#39;cars&#39;);
}

}


Here is the &quot;cars&quot; 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 &quot;car_models&quot; 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 &quot;cars&quot; 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 &quot;Car&quot; model:

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class Car extends Model
{
use HasFactory;

protected $table = &#39;cars&#39;;
protected $primaryKey = &#39;id&#39;;

// public $timestamps = true;

protected $fillable = [&#39;name&#39;, &#39;founded&#39;, &#39;description&#39;];
public function carModels() {
return $this -&gt; hasMany(CarModel::class, &#39;id&#39;, &#39;car_id&#39;);
}

}


Here is the &quot;CarModel&quot; 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 -&gt; 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 &quot;foreign key&quot; and &quot;local key&quot; to the hasMany() in the &quot;Car&quot; model. However, the resulting webpage says &quot;No models found&quot; when it should display &quot;A1 A3 A5&quot;
[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>

&lt;ul&gt;
&lt;p class=&quot;text-lg text-gray-700 py-3&quot;&gt;Models:&lt;/p&gt;
@forelse ($car -&gt; carModels as $model)
&lt;li class=&quot;inline italic text-gray-600 px-1 py-6&quot;&gt;
{{ $model[&#39;model_name&#39;] }}
&lt;/li&gt;  
@empty
&lt;p&gt;No models found&lt;/p&gt;
@endforelse
&lt;/ul&gt;
&lt;hr class=&quot;mt-4 mb-8&quot; /&gt;      

</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&#39;s wrong.
In the &quot;CarModels&quot; model, the protected $table should be &quot;car_models,&quot; not &quot;cars.&quot;
</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-&gt;hasMany(CarModel::class,&#39;car_id&#39;);
}

no need to give column name id

huangapple
  • 本文由 发表于 2023年2月6日 21:40:23
  • 转载请务必保留本文链接:https://go.coder-hub.com/75362056.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定