个性化阅读
专注于IT技术分析

Laravel数据库中的关系

本文概述

Eloquent的关系是Laravel中非常重要的功能, 它使你能够以非常简单的格式关联表。

一对一关系

一对一关系提供了不同表的列之间的一对一关系。例如, 每个用户都与一个帖子或多个帖子相关联, 但是在这种关系中, 我们将检索用户的单个帖子。要定义关系, 我们首先需要在User模型中定义post()方法。在post()方法中, 我们需要实现可返回结果的hasOne()方法。

让我们通过一个例子来理解一对一的关系。

  • 首先, 我们在名为posts的现有表中添加新列(user_id)。在此, user_id是外键。
Laravel数据库中的关系
  • 使用以下命令迁移数据库中的以上更改:php artisan migration。
  • 迁移后, 以下屏幕快照显示了posts表的结构:
Laravel数据库中的关系

上面的屏幕快照显示成功添加了user_id列。

  • 打开User.php文件, 并在User.php文件中添加以下代码。
public function post()
{
  return $this->hasOne('App\Post');
}

在上面的代码中, 我们实现了hasOne()方法, 该方法包含单个参数, 即相关模型的名称。默认情况下, Post将user_id视为外键。正如我们提到的名称空间“ App / Post”一样, post()方法搜索posts表, 并查找user_id列。我们可以通过提供外键作为第二个参数来覆盖此约定。可以将其重写为:

返回$ this-> hasOne(’App \ Post’, foreign_key)

  • 现在, 我们将路由添加到web.php文件中。
<?php
use App\User;
Route::get('/user', function()
{
  return User::find(1)->post;
}
);

上面的代码是查找ID号为1的用户, 然后实现帖子以查找user_id等于1的用户的帖子。

输出量

Laravel数据库中的关系

逆关系

逆关系是指一对一关系的逆关系。在上面, 我们检索了属于特定用户的帖子。现在, 我们根据帖子检索用户信息。让我们通过一个例子来理解这一点。

  • 首先, 我们在web.php文件中创建路由。
<?php
use App\Post;
Route::get('/post/user', function()
{
 return Post::find(1)->user->name;
});
  • 打开我们之前创建的Post.php文件(模型)。
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
class Post extends Model
{
 use SoftDeletes;
protected $table='posts';
protected $primaryKey='id';
protected $fillable=
[
'title', 'body'
];
protected $dates=['deleted_at'];
public function user()
{
  return $this->belongsTo('App\User');
}

}

输出量

Laravel数据库中的关系

一对多关系

Laravel还提供一对多关系。

  • 首先, 我们定义查找单个用户所有帖子的路线。
Route::get('/posts', function(){
$user=User::find(1);
foreach($user->posts as $post){
echo $post->title."<br>";
}
});
  • 在User.php(model)文件中添加以下代码。
public function posts()
{
    return $this->hasMany('App\Post', 'user_id');
}

输出量

Laravel数据库中的关系

多对多关系

多对多关系比一对一关系和一对多关系更为复杂。要定义多对多关系, 我们需要创建一个数据透视表。数据透视表基本上是一个将两个表关联起来的查找表。例如, 一个用户可能具有不同的角色, 这些角色可以由其他用户共享, 就像许多用户可以具有“管理员”角色一样。要定义用户和角色之间的关系, 我们需要创建三个表, 用户, 角色和role_user。在我们的数据库中, 用户表已经创建;我们需要创建两个表, 即角色表和数据透视表(roles_user)。

  • 首先, 我们创建角色模型。我们使用以下命令创建模型:php artisan make:model Role -m
Laravel数据库中的关系

上面的屏幕显示角色表已创建。 create_roles_table.php已在数据库/迁移目录中创建。该文件的结构如下:

<?php
 use Illuminate\Support\Facades\Schema;
 use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateRolesTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('roles', function (Blueprint $table) {
            $table->bigIncrements('id');
            $table->string('name');
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('roles');
    }
}

在上面的代码中, 我们添加了名为“ name”的新列。 “名称”列定义用户角色的名称。

  • 现在, 我们有两个表, 角色表和用户表。为了关联这两个表, 我们需要创建数据透视表角色_用户表。
Laravel数据库中的关系

上面的屏幕显示Roles_user表已创建。下面给出了create_roles_user_table的结构:

<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateRolesUserTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('roles_user', function (Blueprint $table) {
            $table->bigIncrements('id');
            $table->integer('user_id');
            $table->integer('role_id');
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('roles_user');
    }
}

在上面的代码中, 我们添加了两个新列, user_id和role_id。

  • 使用以下命令迁移所有上述更改:php artisan migration
Laravel数据库中的关系
  • 以下屏幕显示了所有三个表, 即角色, roles_user和用户已创建。
Laravel数据库中的关系

角色表中可用的数据:

Laravel数据库中的关系

用户表中可用的数据:

Laravel数据库中的关系

role_user表中可用的数据:

Laravel数据库中的关系
  • 现在, 我们定义路线。

web.php

Route::get('/roles/{id}', function($id){
$user=User::find($id);
foreach($user->role as $role)
{
   return $role->name;
}
});
  • 我们在与两个表相关的User.php文件中添加以下代码。
public function role()
{
   return $this->belongsToMany('App\Role', 'roles_user');
}

在上面的代码中, belongsToMany()方法包含两个参数:“ App \ Role”(使用角色模型的命名空间), “ roles_user”是关联两个表的数据透视表的名称。 EmiratesToMany()方法也可以写成:

ownersToMany(’App \ Role’, ‘roles_user’, ‘user_id’, ‘role_id’);

上一行包含另外两个参数, user_id和role_id。 user_id是用户表的外键, 而role_id是角色表的外键。

输出量

Laravel数据库中的关系
Laravel数据库中的关系

访问中间/数据透视表

在多对多关系中, 我们创建数据透视表或中间表。现在, 我们将看到如何检索此数据透视表。

<?php
Use App\User;
Route::get('/pivot', function(){
$user=User::find(1);
foreach($user->role as $role)
{
   return $role->pivot;
}
});

在上述模型中, 我们检索ID等于1的用户。然后, 使用foreach循环, 检索角色模型并在ivot属性中分配。

Laravel数据库中的关系

如果我们要从数据透视表中检索特定列,

public function role()
{
return $this->belongsToMany('App\Role', 'roles_user')->withPivot('created_at');
}

web.php

Route::get('/pivot', function(){
$user=User::find(1);
foreach($user->role as $role)
{
   return $role->pivot->created_at;
}
});

输出量

Laravel数据库中的关系

有很多通过

“具有很多通过”关系提供了访问遥远或中间关系的便捷方法。例如, 我们有三个表, 用户, 帖子和国家/地区表。现在, 我们要通过用户模型查找属于该国家的帖子。

让我们通过一个例子来理解。

  • 国家/地区表在数据库中不可用。我们首先通过数据库迁移创建国家模型。
Laravel数据库中的关系
  • 在国家/地区表中添加“名称”列。
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateCountriesTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
            Schema::create('countries', function (Blueprint $table) {
            $table->bigIncrements('id');
            $table->string('name');
            $table->timestamps();
        });
    }
/**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('countries');
    }
}
  • 使用以下命令迁移上述更改:php artisan migration
  • 现在, 我们在用户表中添加新列“ country_id”。使用下面给出的命令:php artisan make:migration add_new_column_column_id -table = users;
  • 执行上述命令后, 将在database / migrations目录中创建add_new_column_column_id文件。
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class AddNewColumnColumnId extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::table('users', function (Blueprint $table) {
            $table->integer('country_id')->unsigned;
        });
    }
 /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::table('users', function (Blueprint $table) {
            $table->dropColumn('country_id');
        });
    }
}

在上面的代码中, 我们在users表中添加了一个新列。

要迁移数据库中的上述更改,

PHP的工匠迁移

  • 打开country.php(model)文件。我们将使用国家/地区模型拉出特定国家/地区的职位。 country.php
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class country extends Model
{
 public function posts(){   
 return $this->hasManyThrough('App\Post', 'App\User', 'country_id', 'user_id');
}
}
  • 现在, 我们添加了提取特定国家/地区帖子的路线。
Route::get('/user/country', function()
{

   $country=country::find(1);
   foreach($country->posts as $post)
   {
     return $post->title;
   }
});

输出量

Laravel数据库中的关系

多态关系

一对多(多态)

多态关系类似于一对多关系。当单个模型在单个关联上属于一种以上类型的模型时, 称为一对一多态关系。例如, 如果我们有三个表, posts, users和photo表, 其中photo表代表与users和posts表的多态关系。

让我们通过一个例子来理解这种关系。

  • 在上一个主题中, 我们已经创建了users和posts表。现在, 我们创建一个照片表。
Laravel数据库中的关系

打开在migrations文件夹中创建的create_photos_table.php文件。

<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreatePhotosTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('photos', function (Blueprint $table) {
            $table->bigIncrements('id');
            $table->string('path');
            $table->integer('imageable_id');
            $table->string('imageable_type');
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('photos');
    }
}

在上面的代码中, 我们添加了三列:path, imageable_id和imageable_type。路径确定图像的路径, imageable_id是用户或帖子的id值, 而imageable_type是模型的类名。

  • 我们将从先前创建的posts表中删除user_id列。
  • 查看数据库表。

帖子表中可用的数据

Laravel数据库中的关系

用户表中可用的数据:

Laravel数据库中的关系

照片表中的可用数据:

Laravel数据库中的关系
  • 打开照片模型文件。
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class photo extends Model
{
//
public function imageable()
{
 return $this->morphTo();
}}
  • 在用户模型文件中添加以下代码。
public function photos()
{
  return $this->morphMany('App\Photo', 'imageable');
}
  • 将以下代码添加到Post模型文件中。
public function photos()
{
  return $this->morphMany('App\Photo', 'imageable');}
  • 现在, 我们将为用户和帖子创建路线。
// Route for the users.
Route::get('/user/photo', function(){
$user=User::find(1);
foreach($user->photos as $photo)
{
   return $photo;
}
});

// Route defined for the posts.
Route::get('/post/photo', function(){
$post=Post::find(1);
foreach($post->photos as $photo)
{
   return $photo;
}

});

输出量

Laravel数据库中的关系
Laravel数据库中的关系

一对多(多态)关系的逆

在本主题中, 我们将执行一对多多态关系的逆运算。到现在为止, 我们已经找到了用户和帖子的图像, 现在我们找到了图像的所有者。

让我们通过一个例子来理解。

我们需要在web.php文件中创建路由。

Route::get('/photo/{id}', function($id)
{
   $photo=Photo::findOrFail($id);
   return $photo->imageable;
});

在上面的代码中, Photo :: findOrFail($ id)方法确定给定id的照片是否存在。如果存在, 则它通过语句’$ photo-> imageable’返回图像的详细信息。

输出量

Laravel数据库中的关系

上面的输出显示了图像的细节。

多对多态关系

在多对多多态关系中, 目标模型由在各种模型之间共享的唯一记录组成。例如, 标签表共享视频和帖子表之间的多态关系。标签表由表, 视频和帖子表共享的唯一标签列表组成。

让我们通过一个例子来理解。

  • 首先, 我们使用数据库迁移创建模型, 这些模型分别命名为Audio, Tag和Taggable。
Laravel数据库中的关系
  • 创建模型后, 我们将编辑其迁移的文件。

打开名为“ create_audio_table”的音频表的迁移文件。

<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateAudioTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('audio', function (Blueprint $table) {
            $table->bigIncrements('id');
            $table->string('name');
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('audio');
    }
}

在上面的代码中, 我们使用命令$ table-> string(’name’);在音频表中创建了name列。

打开名为“ create_tag_table”的Tag模型的迁移文件。

<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateTagsTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('tags', function (Blueprint $table) {
            $table->bigIncrements('id');
            $table->string('name');
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('tags');
    }
}

在上面的代码中, 我们使用命令$ table-> string(’name’);在标签表中创建了name列。

打开名为“ create_taggables_table”的Taggable模型的迁移文件。

<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateTaggablesTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('taggables', function (Blueprint $table) {
            $table->bigIncrements('id');
            $table->integer('tag_id');
            $table->integer('taggable_id');
            $table->string('taggable_type');
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('taggables');
    }}

在上面的代码中, 我们在taggables表中添加了三个新列, 即tag_id, taggable_id和taggable_type。 tag_id代表标签表的ID, taggable id代表模型表的ID, taggable type代表类的名称。

  • 要迁移上述更改, 我们使用下面给出的命令:php artisan migration
  • 查看数据库表:

音频表中可用的数据:

Laravel数据库中的关系

帖子表中可用的数据:

Laravel数据库中的关系

标签表中可用的数据:

Laravel数据库中的关系

可标记表中可用的数据:

Laravel数据库中的关系
  • 现在, 我们在模型上定义关系。

Audio.php

<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Audio extends Model
{
  // get all the tags from the audio. 
  public function tags()
  {
    return $this->morphToMany('App\Tag', 'taggable');
  }
}

Post.php

namespace App;
use App\Photo;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
class Post extends Model
{
// get all the tags from this post.
public function tags()
{
  return $this->morphToMany('App\Tag', 'taggable');
}
}
  • 现在我们定义路线。
use App\Post;
use App\Audio;
// Route for getting the tags from the Post model.
Route::get('/post/tags', function()
{
  $post=Post::find(1); 
  foreach($post->tags as $tag)
  {
    return $tag->name;
  }});
//Route for getting the tags from the Audio model.
Route::get('/audio/tags', function()
{
  $audio=Audio::find(1); 
  foreach($audio->tags as $tag)
  {
    return $tag->name;
  }});

输出量

访问帖子的路线时, 输出为:

Laravel数据库中的关系

访问音频路由时, 输出为:

Laravel数据库中的关系

多对多(多态)关系的逆

在多对多多态关系中, 我们发现了属于帖子和音频模型的标签。但是, 在多对多的逆关系中(多态), 我们将找出属于特定标签的所有帖子和音频。

让我们通过一个例子来理解。

  • 首先, 我们在标签模型中定义方法。

Tag.php

<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Tag extends Model
{
   // get all the posts from the tag. 
   public function posts()
    {
      return $this->morphedByMany('App\Post', 'taggable'); 
    }
// get all the audios from the tag.
public function audios()
    {
      return $this->morphedByMany('App\Audio', 'taggable'); 
    }
}

在上面的代码中, 我们定义了两个方法, posts()和audios()。在posts()方法中, 我们检索属于指定标签的所有帖子。在audios()方法中, 我们将检索属于指定标签的所有音频。

  • 现在, 我们定义路线。
use App\Tag;
// Route for getting all the posts of a tag.
Route::get('/tag/post/{id}', function($id){
$tag=Tag::find($id);
foreach($tag->posts as $post)
{
   return $post->title;
}
});
// Route for getting all the audios of a tag.
Route::get('/tag/audio/{id}', function($id){
$tag=Tag::find($id);
foreach($tag->audios as $audio)
{
   return $audio->name;
}
});

输出量

Laravel数据库中的关系
Laravel数据库中的关系

赞(0)
未经允许不得转载:srcmini » Laravel数据库中的关系

评论 抢沙发

评论前必须登录!