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]);
}
复制代码

就这样完成了一个多对多的关联模型,并且是一个比较特殊的。这个弄懂了,其余的关联模型,应该就没啥问题了吧~

相关文章
相关标签/搜索