Laravel——你真的熟悉關聯模型麼?

目前只是學習了thinkphplaravel的框架,對於關聯查詢這一塊,更偏心laravel的寫法,因此這裏就談談我對laravel關聯模型的用法吧。php

舉例:用戶與用戶之間的,被關注者與粉絲的關係

簡單而言,一個用戶能夠關注多我的,而一個用戶也能夠擁有多個粉絲,因此他們之間的關係是屬於多對多的。
很少說,先用數據庫遷移把表創一下。(這裏users的遷移表框架默認有)laravel

$ php artisan make:migration create_followers_table --create="followers"
複製代碼

打開剛剛建立的database/migrations/..create_followers_table.php作出以下改動。thinkphp

.
.
public function up() {
    Schema::create('followers', function(Blueprint $table) {
        $table->increments('id');
        $table->integer('user_id')->index();
        $table->integer('follower_id')->index();
        $table->timestamps();
    });
}
.
.
複製代碼

遷移表字段配置好了,執行遷移數據庫

php artisan migrate
複製代碼

數據庫裏就生成了followers表,接下來開始在User模型裏進行編寫關聯關係了。
打開你的模型user.php數組

.
.
//一個用戶擁有多個粉絲
public function fans() {
    return $this->belongsToMany(User::class, 'followers', 'user_id', 'follower_id');
}

//一個用戶能夠關注多個大佬
public function followings() {
    return $this->belongsToMany(User::class, 'followers', 'follower_id', 'user_id');
}
複製代碼

這裏解釋一下belongsToMany方法四個參數:
第一個參數是關聯的模型,那確定是User模型,沒得說。
第二個參數是表名,這裏個人中間表的表名爲followers
第三個參數呢,是定在關聯模型的模型外鍵名。拿第一個fans()通俗的說,是獲取粉絲列表的嘛,那麼當前你是屬於user_id的關係。你不是follower_id
第四個參數呢,則是你要合併的模型外鍵名,也就是你須要的模型外鍵名,仍是拿fans()方法來講,你是須要關聯來合併查詢到粉絲嘛,因此外鍵呢就是follower_idbash

用法:

  1. 好比查詢當前用戶的全部粉絲:
$fans = Auth::user()->fans;
複製代碼

哇塞,這個是啥意思呀, 其實這個等同於session

$fans = Auth::user()->fans()->get();
複製代碼
  1. 哇,這我的真是大佬,我想要關注她
    先在User.php模型裏有下面的邏輯代碼:
//模型裏的判斷是否關注的方法
private function isFollowing($user_id) {
    return $this->followings->pluck('id')->contains($user_id);
}
//模型裏的關注方法
public function follow($user_ids) {
    //若是$user_ids不是數組
    if(!is_array($user_ids)) {
        $user_ids = compact($user_ids); //轉化爲數組
    }
    
    $this->followings()->sync($user_ids, false);
}
複製代碼

解釋一下上面的兩個方法。
首先,$this->followings和我第 1 點說的同樣,查出當前用戶模型對應的user關注了的全部大佬。
其次用查出來的集合,調用集合方法pluck('id')拿出全部id
再繼續調用contains($user_id)看是否包含$user_id
這裏皮一下:框架

return $this->followings->pluck('id')->contains($user_id);
//等價於
return $this->followings->contains($user);
//至於爲何呢? 由於laravel裏模型會對應到主鍵,我是這麼理解的
複製代碼

而後這裏有幾條邏輯:學習

  • 說不定這個大佬是你本身,你確定患了健忘症。
  • 判斷是否已經關注了她,可能你忘了對吧。
  • 都沒問題,那就關注把。
    根據邏輯在控制器裏寫關注的方法:
public function store(User $user) {
    //說不定這個大佬是你本身,你確定患了健忘症
    if(Auth::id() === $user->id) {
        return redirect('/');
    }
    //判斷是否已經關注了她,可能你忘了對吧
    if(Auth::user()->isFollowing($user->id)) { //模型裏判斷是否關注的方法
        session()->flash('notice', '你已經關注過他了喲,不須要重複關注');  
        return redirect()->back();
    }
     Auth::user()->follow($user->id); //模型裏的關注方法
    return redirect()->route('users.show', [$user]);    //上面說過模型也是主鍵
}
複製代碼
  1. 不行,我忽然關注錯了,我要取消關注那我的。
    同樣,先在User模型裏寫方法。
public function unfollow($user_ids) {
    //若是不是數組
    if(!is_array($user_ids)) {
        $user_ids = compact($user_ids);
    }
    
    $this->followings()->detach($user_ids);
}
複製代碼

而後下面有幾條邏輯:this

  • 說不定這個大佬是你本身,你確定患了健忘症。
  • 你根本就沒關注過別人好嗎
  • 沒問題了,取消關注把
public function destroy(User $user) {
    //說不定這個大佬是你本身,你確定患了健忘症
    if(Auth::id() === $user->id) {
        return redirect('/');
    }
    //你根本就沒關注過別人好嗎
    if(!Auth::user()->isFollowing($user->id)) {
        session()->flash('notice', '你尚未關注過他喲,不須要取消關注');  
        return redirect()->back();
    }
    //沒問題了,取消關注吧
    Auth::user()->unfollow($user->id);
    return redirect()->route('users.show', [$user]);
}
複製代碼

就這樣完成了一個多對多的關聯模型,並且是一個比較特殊的。這個弄懂了,其餘的關聯模型,應該就沒啥問題了吧~

相關文章
相關標籤/搜索