我想澄清一个关于Laravel的问题。这些是迁移/表级别(外键)和模型级别(ORM Eloquent)的关系。
我提出一个我目前正在工作的例子,非常简单。我们有3 张桌子(Worlds、Classes、Races。
要考虑的关系的基数:
1 个 世界有N个 职业,另一方面,1 个 世界有N个 种族
说了这么多,让我们继续讨论问题:
让我们从迁移开始。我将根据前面提到的表格来举例说明:
世界移民
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateMundosTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('mundos', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('nombre')->unique();
$table->string('descripcion');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('mundos');
}
}
好吧,世界表没有外键,所以我只是用它的字段创建迁移,就是这样。到目前为止,没有任何疑问或问题。让我们
继续……类迁移
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateClasesTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('clases', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('nombre')->unique();
$table->string('descripcion');
$table->timestamps();
$table->bigInteger('mundo_id');
$table->foreign('mundo_id')->references('id')->on('mundos');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('clases');
}
}
种族迁移
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateRazasTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('razas', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('nombre')->unique();
$table->string('descripcion');
$table->timestamps();
$table->bigInteger('mundo_id');
$table->foreign('mundo_id')->references('id')->on('mundos');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('razas');
}
}
在最后两次迁移(阶级迁移和种族迁移)中,出现了以下疑问:
我认为就迁移而言,关系(在这种情况下是从一对多,是经过深思熟虑的,我不认为这是错误的)但这仅适用于迁移部分。Eloquent(ORM)呢?也就是说,每个迁移对应一个模型。
在这种情况下,我将使用两个模型(Class 和 Race)之一,因为它毕竟是相同的,并且将应用相同的方法,因为两者它们是1-N关系。让我们以Race模型为例:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Raza extends Model
{
//
}
如果您注意到,在模型(ORM 雄辩)的部分我不会在任何时候表明模型之间的关系,因为我这样做是在迁移级别。但是对于模型,据我所知,它不知道模型之间的关系。我的疑问是:
1)表之间的关系是否应该在迁移级别(就像我所做的那样)和模型级别(在我的情况下我有一个空模型)完成?
2)如果答案是肯定的,我是否必须在我的模型上放这样的东西?:
public function comments()
{
return $this->hasMany('App\Comment');
}
3)为什么要在函数中,名称的含义是什么?
4)在迁移级别而不是在模型级别建立关系是否不好?我不明白需要做两次(迁移和模型)
1)表之间的关系是否应该在迁移级别(就像我所做的那样)和模型级别(在我的情况下我有一个空模型)完成?
迁移关系在数据库级别有所帮助,不要忘记数据库非常独立于php (
laravel
) 中发生的事情,例如,当试图通过外键消除具有依赖元组的元组时,数据库会通知我们这个元组在没有更多依赖项之前不能被消除。在模型级别建立关系是在 laravel(php) 中处理的,正如我所说的,它与数据库无关,这些关系使得用Eloquent查询更容易,而且查询不需要知道 sql .
所以答案是:在这两者中都不是强制性的,在迁移中它会尽可能地保持您的数据库和模型中的完整,以便在开发时您的生活更轻松。;)
2)如果答案是肯定的,我是否必须在我的模型中添加这样的东西?:
答:有几种方法可以执行关系:
因此,我邀请您阅读Laravel 文档,因为那里对它们进行了详细解释,我认为没有比这更好的了。
3)为什么要在函数中,名称的含义是什么?
取决于模型之间存在的关系:如果 1 个世界有 N 个类别,则其逆将是:1 个类别属于 1 个世界,那么在您的模型中,您将有如下内容:
您会看到主题的简单性。
访问和使用:
4)在迁移级别而不是在模型级别建立关系是否不好?我不明白需要做两次(迁移和模型)
我想我已经解释了所有内容,不需要重复两次,但是如果您不想对进度或系统本身有问题,我建议您继续这样做。
首先,你说:
好吧,在 World 模型中,您应该与 Classes 和 Races 有关系。在 Classes 模型中,您应该具有与 World 相关的关系,而在 Races 模型中,您应该具有与 World 相关的关系。
但是,在模型中定义这些关系之前,您必须清楚它是一种什么样的关系,因为任何事物都有对应的关系,这种关系是一对一、一对多还是多对多。
例子:
是的:
A) 如果一个类属于一个单一的世界,它将是一对多的关系。
B) 如果一个类属于多个世界,那么您将处于多对多关系中。
例如,如果是选项 (A) 的情况:
对于一对多的关系,
Mundo 模型应该具有:
Race 模型的对应物,在一对多的关系中,将是:
注意函数名称的单数或复数,这很重要。由于 1 World 有许多 Races,因此您将用于了解与 id = 1 的 World 对应的类的雄辩查询将很简单:
关于迁移:
对于这种类型的关系(一对多),在这种情况下,品种表必须具有:
该字段必须命名,其对应物(世界)的模型名称与“_id”连接。
我认为正如您所做的那样,在迁移中定义外键是一种很好的做法,尽管您也可以在模型函数中指定它们。