【再讀lara】Eloquent: Relationship 關(guān)聯(lián)

一對一

用戶和文章

namespace App;

use Illuminate\Database\Eloquent\Model;

class User extends Model
{
  public function post()
  {
    return $this->hasOne('App\Phone');
  }
}

在當(dāng)前場景下,Eloquent 會假設(shè) Phone 模型有一個外間 user_id
$phone = User::find(1)->post;


反向關(guān)聯(lián)
namespace App;

use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
  public function user()
  {
    return $this->belongsTo('App\User');
  }
}

空對象模型, user 關(guān)聯(lián)如果沒有找到文章的作者,就會返回一個空的 App\User 模型。
可以理解返回一個默認值,還沒有具體實踐過
class Post extends Model
{

  // 數(shù)組形式
  public function user()
  {
    return $this->belongsTo('App\User')->withDefault([
      'name' => '游客'
    ]);
  }

    // 閉包形式
    public function user() 
    {
      return $this->belongsTo('App\User')->withDefault(function($user) {
        $user->name = '游客';
      });
    }
}

一對多

文章和評論

文章
namespace App;

use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
  public function comments()
  {
    return $this->hasMany('App\Comment');
  }
}


評論
namespace App

use Illuminate\Database\Eloquent\Model;

class Comment extends Model
{
  public function post()
  {
    return $this->belongsTo('App\Post');
  }
}

多對多

用戶和角色
一個用戶可以擁有多個角色,一個角色下面可以有多個用戶
users, roles, role_user 三張表
role_user 表是以相關(guān)聯(lián)的兩個模型數(shù)據(jù)表、依照字母順序排列命名的,并且包含 user_id 和 role_id 字段。

namespace App;

use Illuminate\Database\Eloquent\Model;

class User extends Model
{
  public function roles()
  {
    return $this->belongsToMany('App\Role');
  }
}


namespace App;

use Illuminate\Databese\Eloquent\Model

class Role extends Model
{
  public function users()
  {
    return $this->belongsToMany('App\User');
  }
}


自定義中間表的場景
namespace App;
use Illuminate\Database\Eloquent\Model;
class Role extends Model
{
  public function users()
  {
    return $this->belongsToMany('App\User')->using('App\RoleUser');
  }
}

namespace App;
use Illuminate\Database\Relationships\Pivot;
class RoleUser extends Pivot
{
   
}

遠層一對多

一個 Country 模型可以通過中間的 User 模型獲得多個 Post 模型

countries
    id - integer
    name - string

users
    id - integer
    country_id - integer
    name - string

posts
    id - integer
    user_id - integer
    title - string


hasManyThrough 方法的第一個參數(shù)是我們最終希望訪問的模型名稱,而第二個參數(shù)是中間模型的名稱。
namespace App;
use Illuminate\Database\Eloquent\Model;
class Country extends Model
{
  // 默認
  public function posts()
  {
    return $this->hasManyThrough('App\Post', 'App\User');
  }

  // 自定義
  第三個參數(shù)表示中間模型的外鍵名,第四個參數(shù)表示最終模型的外鍵名。
  第五個參數(shù)表示本地鍵名,而第六個參數(shù)表示中間模型的本地鍵名:
  public function posts()
  {
    return $this->hasManyThrough(
      'App\Post', 
      'App\User',
      'country_id',    // 用戶表外鍵
      'user_id',         // 文章表外鍵
      'id',                  // 國家表
      'id'                   //
    );
  }
}

多態(tài)關(guān)聯(lián)

用戶可以「評論」文章和視頻

commentable_id 用來保存文章或者視頻的 ID 值
commentable_type 用來保存所屬模型的類名 (post, video)
posts
    id - integer
    title - string
    body - text

videos
    id - integer
    title - string
    url - string

comments
    id - integer
    body - text
    commentable_id - integer
    commentable_type - string


namespace App;
use Illuminate\Database\Eloquent\Model;

class Comment extends Model
{
  public function commentable()
  {
    return $this->morphTo();
  }
}

class Post extends Model
{
  public function comments()
  {
    return $this->morphMany('App\Comment', 'commentable');
  }
}

class Video extends Model
{
  public function comments()
  {
    return $this->morphMany('App\Comment', 'commentable');
  }
}


$commentable = App\Comment::find(1)->commtable();
返回 commentable 的 Post 或 Video 實例

多對多多態(tài)關(guān)聯(lián)

Post 和 Video 兩個模型都有一個 tags 方法,方法內(nèi)部都調(diào)用了 Eloquent 類自身的 morphToMany 方法

posts
    id - integer
    name - string

videos
    id - integer
    name - string

tags
    id - integer
    name - string

taggables
    tag_id - integer
    taggable_id - integer
    taggable_type - string


namespace App;
use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
  public function tags()
  {
    return $this->morphToMany('App\Tag', 'taggable');
  }
}


反向關(guān)聯(lián)
class Tag extends Model
{
  public function posts()
  {
    return $this->morphedByMany('App\Post', 'taggable');
  }

  public function videos() 
  {
    return $this->morphedByMany('App\Video', 'taggable');
  }
}

$tags = Post::find(1)->tags;

或者
$tag = Tag::find(1);
$videos = $tag->videos;

Dynamic properties allow you to access relationship methods as if they were properties defined on the model
模型中定義的關(guān)聯(lián),叫做 dynamic property(動態(tài)屬性)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容