一、描述1vs1關係php
例如好比又兩張表,一張用戶表,一張手機表,一個用戶只有一個手機,一個手機也只屬於一我的,就表達了一對一的關係ide
class User extends Eloquent {
//一對一
public function phone() {
return $this->hasOne('Phone'); // this matches the Eloquent model
}
函數
class Phone extends Eloquent {
public function user() {
return $this->belongsTo('user'); // this matches the Eloquent model
}post
咱們能夠總結出,在一對一關係中,主表(也就是沒有保存user_id表的那個表),用hasOne表示,另一個表,保存了user_id的,用belongsTo來表述。換句話說,當咱們看到一個表有blongsTo的時候,若是後面沒有帶參數,也就表明着這個表利用方法名_id來跟前面的表關聯.this
$account = User::find(10)->phone;
這裏最難的地方在於後面的兩個 foreign_key 和 local_key 的設置,你們能夠就此記住:在 User 類中,不管 hasOne 誰,第二個參數都是 `user_id`,第三個參數通常都是 `id`。因爲前面的 `find(10)` 已經鎖定了 id = 10,因此這段函數對應的 SQL 爲: `select * from phone where user_id=10`。spa
這段代碼除了展現了一對一關係該如何使用以外,還傳達了三點信息,也是我對於你們使用 Eloquent 時候的建議:code
1. 每個 Model 中都指定表名視頻
2. has one account 這樣的關係寫成 `hasOneAccount()` 而不是簡單的 `account()`對象
3. 每次使用模型間關係的時候都寫全參數,不要省略string
二、描述1vs多關係
例如班級表,學生表,一個班級有不少名學生,一個學生只在一個班級,所以class表跟student表是一對多關係
class Squad extends Eloquent {
//一對多
public function student() {
return $this->hasMany('Student');
}
class Student extends Eloquent {
public function squad() {
return $this->belongsTo('Squad');
}
咱們能夠總結出,在一對多關係中,主表(也就是沒有保存squad_id表的那個表),用hasMany表示,另一個表,保存了squad_id的,用 belongsTo來表述。
三、描述多對多關係
例如角色表,用戶表,一個角色有多個用戶,一個用戶能夠擁有多個角色
Class Role extentds Eloquent{
public function users{
return $this->belongsToMany('App\User','user_roles');
}
}
Class User extentds Eloquent{
//多對多關係咱們都用複數
public function roles{
return $this->belongsToMany('App\role','user_role');
//(被關聯模型,中間表名,關係模型(本類的外鍵id)的外鍵名稱,鏈接到的外鍵名)
return $this->belongsToMany('App\Role', 'user_roles', 'user_id', 'role_id');
}
}
PS:其實咱們並不是必定要在咱們的模型中寫這麼多可能另咱們本身都費解的東西,只是根據須要咱們須要進行某些查詢的時候才寫,舉個簡單例子,若是咱們只須要查一個角色有多少個用戶,而咱們發現角色跟用戶是多對多關係,咱們就能夠在Role表中寫個User方法。若是咱們須要查一個班級的全部學生,咱們發現班級跟學生是一對多關係,咱們就能夠在班級模型中寫Student方法,用到hasMany。凡是看到有belongsToMany的該模型跟括號裏面的確定是多對多。
四、傳統多態模型
文章有點贊功能,評論也有點贊功能,咱們的點贊表就有一個字段用來記錄表的類型,id記錄了文章或評論的id
posts id - integer title - string body - text comments id - integer post_id - integer body - text likes id - integer likeable_id - integer likeable_type - string
<?php namespace App; use Illuminate\Database\Eloquent\Model; class Like extends Model{ /** * 獲取所屬的likeable模型 */ public function likeable() { return $this->morphTo(); } } class Post extends Model{ /** * 獲取該文章的全部點贊 */ public function likes() { return $this->morphMany('App\Like', 'likeable'); } } class Comment extends Model{ /** * 獲取該評論的全部點贊 */ public function likes() { return $this->morphMany('App\Like', 'likeable'); } }
傳統的多態比較好理解,就是在文章或評論裏面用一個morphMany方法進行關聯。傳統的多態關聯是基於多個一對多表之間的對應關係。
五、多對多的多態關聯
多對多的多態關聯就稍微複雜點,利用到了相似於咱們說的中間表概念,例如咱們的文章跟視頻均可能有多個標籤,因而咱們就有了標籤表跟標籤關聯表。
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
關聯主體表用morphTomany:
<?php namespace App; use Illuminate\Database\Eloquent\Model; class Post extends Model{ /** * 獲取指定文章全部標籤 */ public function tags() { return $this->morphToMany('App\Tag', 'taggable'); } }
被關聯也就是多態模型表用morphedByMany。
<?php namespace App; use Illuminate\Database\Eloquent\Model; class Tag extends Model{ /** * 獲取全部分配該標籤的文章 */ public function posts() { return $this->morphedByMany('App\Post', 'taggable'); } /** * 獲取分配該標籤的全部視頻 */ public function videos() { return $this->morphedByMany('App\Video', 'taggable'); } }
這是一個主體經過某個中間表在另一個表中多態的例子,還有一種
通知表notifies,通知發送對象notify_pivots表(一條通知可能發送給一我的,也多是一個班級,也多是一個學校),所以這就造成了notifies表經過users表,school表,squards表跟notify_pivots表關聯。
notify模型
public function schools() { return $this->morphedByMany('App\Models\School','notify_pivots'); } // public function squads() { return $this->morphedByMany('App\Models\Squad','notify_pivots'); } // 這個是消息的接收者是學生或者老師或者其它的方法 public function users() { return $this->morphedByMany('App\Models\User','notify_pivots'); }