到目前为止,我们构建了一个很棒的应用程序,可让用户保存任务。但是现在,我们希望将其更进一步,并单独保存每个用户的任务。这意味着每个用户将拥有自己的一组任务。当然,我们将确保将任务与登录应用程序登录的当前用户联系起来。因此,他们很容易访问其任务。听起来很酷,对
关系数据库管理系统(RDBMS)是一种基于关系工作的数据库管理系统。基本上,使用一组相关表进行了数据和关系。许多流行的 dbmss 喜欢 sqlite , mysql , Microsoft Access 遵循此结构。
现在,谈论不同类型的数据库管理结构超出了本文的范围。但是,如果您感到好奇并想探索有关各种DBMS的更多信息,则可以查看以下链接:
好吧,让我们深入研究模型中定义关系的主题。
当涉及到桌子关系时,我们遇到的主要关系是一对多和一到一对一对一。在一对一的关系中,一个表中的每个记录都链接到另一表中的一个记录。例如,想想学生和他们的帐户详细信息之间的联系:
另一方面,在一对多关系中,一个表中的每个记录都可以与另一表中的多个记录相关联。窥视下图:
您会注意到每个客户可以有几个订单,但每个订单仅属于一个客户。
,嘿,不要忘记另一种称为多一到多的关系。为了处理这一点,我们使用接口表将其转换为两个一对多的关系。查看下图:
您会看到课程与学生表之间的多对多关系,我们使用与两个一对多关系的接口表进行了转换。
在我们的示例中,每个用户都与自己的任务集相关联。
这是如何工作的:一个用户可以具有多个任务,但是每个任务仅属于一个用户。因此,要实现这一目标,我们需要更新任务模型迁移文件,并引入一个称为foreferid的新属性。此属性将负责将用户与任务之间的连接存储。
为了建立此连接,我们可以使用来自用户表中的任何唯一数据。在我们的设计中,我们有电子邮件和ID等选项。
这是一个有用的提示:在关系数据库中,我们经常使用ID,因为它优化了相关模型的检索。
让我们更新我们的迁移文件并添加foreignId
:
Schema::create('tasks', function (Blueprint $table) {
$table->id();
$table->string('title');
$table->text('description')->nullable();
$table->foreignId('user_id')->constrained();
$table->timestamp('expired_at')->nullable();
$table->timestamps();
});
您可能已经注意到,我在这里使用了一个方便的功能,称为constrained
。其主要目的是在表中建立模型之间的关系。此功能为属性添加了额外的信息,例如相关模型的表名称。在这种情况下,相关模型是users
表。
您实际上可以像constrained('users')
一样明确指定表名称,但是此功能足够聪明,可以根据foreignId
属性名称自动弄清楚它。
现在我们更新迁移文件,让我们更新表:
php artisan migrate:fresh --force
做得好!现在,让我们谈谈我们如何在项目中实际使用它。
在Laravel中,雄辩提供了一些方便的辅助功能来定义关系。在我们的情况下,由于任务模型属于用户,因此我们可以简单地在任务模型中定义belongsTo
函数:
class Task extends Model
{
public function user()
{
return $this->belongsTo(User::class);
}
}
对于我们的用户来说,可以有许多任务,我们可以使用hasMany
函数:
class User extends Authenticatable
{
public function tasks()
{
return $this->hasMany(Task::class);
}
}
当然,我们在项目中还没有多一对,但让我们谈论这种令人兴奋的关系。好消息是,这两种型号都更简单!我们只需要使用belongsToMany
函数。这些功能通常是我们定义关系所需的全部。但是,如果您正在寻找更详细的解释,则可以在这里找到它们:
这些功能具有一些非常方便的应用程序。可以说我们有一项任务,我们想知道创建它的用户的名称。在这种情况下,我们如何解决它:
$task = Task::find(1);
$task->user->name;
这是您应该知道的:在我们的任务模型中,我们获得了称为“用户定义”的酷功能。现在,您可能想知道为什么我们将其用作属性,而没有这些括号。
好吧,让我解释一下。当我们将这些函数视为属性时,几乎就像我们直接使用查询指定用户模型本身一样。这就是为什么我们可以像用户名称一样轻松访问属性。这是获取我们需要的信息的便利方法!
让任务功能练习它:
如上图中所示,您可以找到特定用户的所有相关模型,或在与该特定用户关联的任务模型上执行任何查询。
现在,让我们回到我们的任务控制器并更新存储功能。目标是为当前用户创建一个新任务并设置用户ID属性。我们可以使用以下代码以非常直接的方式实现这一目标:( auth()->id()
获取当前登录的用户ID):
$task = new Task();
$task->title = request('title');
$task->descripton = request('descripton');
$task->expired_at = request('expired_at');
$task->user_id = auth()->id();
$task->save();
但是,让我使用任务功能向您介绍一个更酷的选项。这种方法提供了一些惊人的好处。检查一下:
public function store(StoreTaskRequest $request)
{
auth()->user()->tasks()->create($request->validated());
return redirect("/tasks", 201);
}
在这里,用户的外国ID由tasks
真棒!现在,让我们更新我们的索引功能以检索与当前登录的用户关联的所有任务。这真的很简单。只需这样的索引函数:
public function index()
{
return view('tasks.index', ['tasks' => auth()->user()->tasks]);
}
也可以利用刀片模板中的auth功能直接访问当前用户的任务。这意味着我们可以删除从索引函数传递的任务变量。相反,我们可以在刀片模板本身中获取所有任务。它非常方便!
在本文中,我们介绍了Laravel中实体与模型之间的关系。我们讨论的信息不仅很重要,而且非常实用。掌握复杂查询是后端工作的任何人的关键技能。希望您发现这个教程愉快而有见地。