Laravel——你真的熟悉关联模型么?

目前只是学习了thinkphplaravel的框架,对于关联查询这一块,更偏爱laravel的写法,所以这里就谈谈我对laravel关联模型的用法吧。

举例:用户与用户之间的,被关注者与粉丝的关系

简单而言,一个用户可以关注多个人,而一个用户也可以拥有多个粉丝,所以他们之间的关系是属于多对多的。
不多说,先用数据库迁移把表创一下。(这里users的迁移表框架默认有)

$ php artisan make:migration create_followers_table --create="followers"
复制代码

打开刚刚创建的database/migrations/..create_followers_table.php做出如下改动。

.
.
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_id

用法:
  1. 比如查询当前用户的所有粉丝:
$fans = Auth::user()->fans;
复制代码

哇塞,这个是啥意思呀, 其实这个等同于

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

然后下面有几条逻辑:

  • 说不定这个大佬是你自己,你肯定患了健忘症。
  • 你根本就没关注过别人好吗
  • 没问题了,取消关注把
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]);
}
复制代码

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值