📜  Laravel关系

📅  最后修改于: 2021-01-05 10:53:10             🧑  作者: Mango

Laravel关系

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

一对一关系

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

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

  • 首先,我们在名为posts的现有表中添加新列(user_id)。在此,user_id是外键。

  • 使用以下命令迁移数据库中的上述更改: php artisan migrate
  • 迁移后,以下屏幕快照显示了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文件中。
post;
}
);

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

输出量

逆关系

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

  • 首先,我们在web.php文件中创建路由。
user->name;
});
  • 打开我们之前创建的Post.php文件(模型)。
belongsTo('App\User');
}

}

输出量

一对多关系

Laravel还提供一对多关系。

  • 首先,我们定义查找单个用户所有帖子的路线。
Route::get('/posts',function(){
$user=User::find(1);
foreach($user->posts as $post){
echo $post->title."
"; } });
  • 在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已在数据库/迁移目录中创建。该文件的结构如下:

bigIncrements('id');
            $table->string('name');
            $table->timestamps();
        });
    }

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

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

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

上面的屏幕显示Roles_user表已创建。下面给出了create_roles_user_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

  • 下面的屏幕显示了所有三个表,即role,roles_user和users已创建。

角色表中可用的数据:

用户表中可用的数据:

role_user表中可用的数据:

  • 现在,我们定义路线。

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是角色表的外键。

输出量


访问中间/数据透视表

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

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;
}
});

输出量

有很多通过

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

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

  • 国家/地区表在数据库中不可用。我们首先通过数据库迁移创建国家模型。

  • 在国家/地区表中添加“名称”列。
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文件。
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
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;
   }
});

输出量

多态关系

一对多(多态)

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

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

  • 在上一个主题中,我们已经创建了users和posts表。现在,我们创建一个照片表。

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

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_idimageable_type 。路径确定图像的路径, imageable_id是用户或帖子的id值,而imageable_type是模型的类名。

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

帖子表中可用的数据

用户表中可用的数据:

照片表中的可用数据:

  • 打开照片模型文件。
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,TagTaggable

  • 创建模型后,我们将编辑其迁移的文件。

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

bigIncrements('id');
            $table->string('name');
            $table->timestamps();
        });
    }

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

在上面的代码中,我们使用命令$ table-> 字符串('name')在音频表中创建了name列

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

bigIncrements('id');
            $table->string('name');
            $table->timestamps();
        });
    }

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

在上面的代码中,我们使用命令$ table-> 字符串('name')在标签表中创建了name列

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

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
  • 查看数据库表:

音频表中可用的数据:

帖子表中可用的数据:

标签表中可用的数据:

可标记表中可用的数据:

  • 现在,我们在模型上定义关系。

Audio.php

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;
  }});

输出量

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

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

多对多(多态)关系的逆

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

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

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

Tag.php

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;
}
});

输出量