本文概述
- 一对一关系
- 逆关系
- 一对多关系
- 多对多关系
- 访问中间/数据透视表
- 有很多通过
- 多态关系
一对一关系 一对一关系提供了不同表的列之间的一对一关系。例如, 每个用户都与一个帖子或多个帖子相关联, 但是在这种关系中, 我们将检索用户的单个帖子。要定义关系, 我们首先需要在User模型中定义post()方法。在post()方法中, 我们需要实现可返回结果的hasOne()方法。
让我们通过一个例子来理解一对一的关系。
- 首先, 我们在名为posts的现有表中添加新列(user_id)。在此, user_id是外键。
文章图片
- 使用以下命令迁移数据库中的以上更改:php artisan migration。
- 迁移后, 以下屏幕快照显示了posts表的结构:
文章图片
上面的屏幕快照显示成功添加了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的用户的帖子。
输出量
文章图片
逆关系 逆关系是指一对一关系的逆关系。在上面, 我们检索了属于特定用户的帖子。现在, 我们根据帖子检索用户信息。让我们通过一个例子来理解这一点。
- 首先, 我们在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还提供一对多关系。
- 首先, 我们定义查找单个用户所有帖子的路线。
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');
}
输出量
文章图片
多对多关系 多对多关系比一对一关系和一对多关系更为复杂。要定义多对多关系, 我们需要创建一个数据透视表。数据透视表基本上是一个将两个表关联起来的查找表。例如, 一个用户可能具有不同的角色, 这些角色可以由其他用户共享, 就像许多用户可以具有“管理员”角色一样。要定义用户和角色之间的关系, 我们需要创建三个表, 用户, 角色和role_user。在我们的数据库中, 用户表已经创建;我们需要创建两个表, 即角色表和数据透视表(roles_user)。
- 首先, 我们创建角色模型。我们使用以下命令创建模型:php artisan make:model Role -m
文章图片
上面的屏幕显示角色表已创建。 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”的新列。 “名称”列定义用户角色的名称。
- 现在, 我们有两个表, 角色表和用户表。为了关联这两个表, 我们需要创建数据透视表角色_用户表。
文章图片
上面的屏幕显示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
文章图片
- 以下屏幕显示了所有三个表, 即角色, roles_user和用户已创建。
文章图片
角色表中可用的数据:
文章图片
用户表中可用的数据:
文章图片
role_user表中可用的数据:
文章图片
- 现在, 我们定义路线。
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是角色表的外键。
输出量
文章图片
文章图片
访问中间/数据透视表 在多对多关系中, 我们创建数据透视表或中间表。现在, 我们将看到如何检索此数据透视表。
<
?php
Use App\User;
Route::get('/pivot', function(){
$user=User::find(1);
foreach($user->
role as $role)
{
return $role->
pivot;
}
});
在上述模型中, 我们检索ID等于1的用户。然后, 使用foreach循环, 检索角色模型并在ivot属性中分配。
文章图片
如果我们要从数据透视表中检索特定列,
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;
}
});
输出量
文章图片
有很多通过 “具有很多通过”关系提供了访问遥远或中间关系的便捷方法。例如, 我们有三个表, 用户, 帖子和国家/地区表。现在, 我们要通过用户模型查找属于该国家的帖子。
让我们通过一个例子来理解。
- 国家/地区表在数据库中不可用。我们首先通过数据库迁移创建国家模型。
文章图片
- 在国家/地区表中添加“名称”列。
<
?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;
}
});
输出量
文章图片
多态关系 一对多(多态)
多态关系类似于一对多关系。当单个模型在单个关联上属于一种以上类型的模型时, 称为一对一多态关系。例如, 如果我们有三个表, posts, users和photo表, 其中photo表代表与users和posts表的多态关系。
让我们通过一个例子来理解这种关系。
- 在上一个主题中, 我们已经创建了users和posts表。现在, 我们创建一个照片表。
文章图片
打开在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列。
- 查看数据库表。
文章图片
用户表中可用的数据:
文章图片
照片表中的可用数据:
文章图片
- 打开照片模型文件。
<
?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;
}});
输出量
文章图片
文章图片
一对多(多态)关系的逆
在本主题中, 我们将执行一对多多态关系的逆运算。到现在为止, 我们已经找到了用户和帖子的图像, 现在我们找到了图像的所有者。
让我们通过一个例子来理解。
我们需要在web.php文件中创建路由。
Route::get('/photo/{id}', function($id)
{
$photo=Photo::findOrFail($id);
return $photo->
imageable;
});
在上面的代码中, Photo :: findOrFail($ id)方法确定给定id的照片是否存在。如果存在, 则它通过语句’ $ photo-> imageable’ 返回图像的详细信息。
输出量
文章图片
上面的输出显示了图像的细节。
多对多态关系
在多对多多态关系中, 目标模型由在各种模型之间共享的唯一记录组成。例如, 标签表共享视频和帖子表之间的多态关系。标签表由表, 视频和帖子表共享的唯一标签列表组成。
让我们通过一个例子来理解。
- 首先, 我们使用数据库迁移创建模型, 这些模型分别命名为Audio, Tag和Taggable。
文章图片
- 创建模型后, 我们将编辑其迁移的文件。
<
?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
- 查看数据库表:
文章图片
帖子表中可用的数据:
文章图片
标签表中可用的数据:
文章图片
可标记表中可用的数据:
文章图片
- 现在, 我们在模型上定义关系。
<
?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;
}});
输出量
访问帖子的路线时, 输出为:
文章图片
访问音频路由时, 输出为:
文章图片
多对多(多态)关系的逆
在多对多多态关系中, 我们发现了属于帖子和音频模型的标签。但是, 在多对多的逆关系中(多态), 我们将找出属于特定标签的所有帖子和音频。
让我们通过一个例子来理解。
- 首先, 我们在标签模型中定义方法。
<
?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视图详解
- Laravel路由参数
- Laravel模板继承
- Laravel会话session
- Laravel路由控制器
- Laravel路由组
- Laravel资源控制器
- Laravel迁移结构
- Laravel将数据传递到视图