为了账号安全,请及时绑定邮箱和手机立即绑定

Laravel 多态关系 - 警报系统

Laravel 多态关系 - 警报系统

PHP
繁花不似锦 2022-06-11 10:30:20
我有 3 个模型,User、Alert和Category。User和之间的关系Category是多对多的。Alert和之间的关系Category也是多对多的。AUser应该只接收Alert属于已选择的相同Category的User。例如,如果将UserTravel和Food作为,Category那么我只想Alert将Travel和Food显示给User。一旦User查看了Alert,Alert则应将该特定 的 标记为“已读” User。目前我正在这样做:Category.phppublic function alerts(){    return $this->belongsToMany('App\Alert')->withTimestamps();}public function users(){    return $this->belongsToMany('App\User')->withTimestamps();}User.phppublic function alerts(){   return $this->belongsToMany('App\Category')->withTimestamps();}public function categories(){   return $this->belongsToMany('App\Alert')->withTimestamps()->withPivot('read');}Alert.phppublic function users(){    return $this->belongsToMany('App\User')->withTimestamps()->withPivot('read');}public function categories(){    return $this->belongsToMany('App\Category')->withTimestamps();}在当前的实现中,有 3 个数据透视表:alert_category、alert_user和category_user。alert_user表有一个名为的额外字段read,它基本上确定用户是否已阅读警报。IEalert_user tablealert_iduser_idread (holds 0 or 1)这个实现有很多缺陷,我认为它根本不起作用,因为 newUser不会收到Alert在注册之前创建的,如果Alert更改Category,它不会被更新。当然,它可以通过显式更新每个表来完成,但我不认为这是有效的,也不是架构。我正在考虑将整个事情重构为多对多的多态关系。但是,我如何确定是否User已阅读特定内容Alert?我应该在哪里放置一个read字段?你怎么看?我对任何想法持开放态度。任何帮助将不胜感激。编辑:总而言之,我想我想做的是,而不是User订阅Alert,它应该订阅Category. 因此,基本上User将收到所有Alert相同的Category。
查看完整描述

2 回答

?
尚方宝剑之说

TA贡献1788条经验 获得超4个赞

如果您希望新注册的用户看到所选类别下的所有以前的警报,基本上就是说登录用户应该看到这些类别下的所有警报。


我不认为将 aalert与 a联系起来user会给你带来任何好处。如果有的话,它会给你增加一层额外的复杂性。


现在,如果您想跟踪 which usersread which alert,您可以使用该alert_user表。基本上,当 auser读取一个alert. created_at将告诉您用户阅读的确切时间alert,因此read也不需要标志。


并且,为了显示警报,您可以查询,例如,与登录用户没有关系记录的警报。你可以使用whereDoesntHave. 例如,像这样:


Alert::whereHas('categories', function($query) use ($category_id_array){


  $query->whereIn('category_id', $category_id_array);


})->whereDoesntHave('users', function($query) use ($user_id){


  $query->where('user_id', $user_id); //user_id is auth()->user()->id


})->get();

如果您只想显示推文而不排除经过身份验证的用户:


Alert::whereHas('categories', function($query) use ($category_id_array){


  $query->whereIn('category_id', $category_id_array);


})->get();


查看完整回答
反对 回复 2022-06-11
?
隔江千里

TA贡献1906条经验 获得超10个赞

如果您希望选择一个用户,然后确定他是否有任何未读警报,那么您可以这样做:


foreach($user->alerts as $alert){

 if($alert->read == 1){

  //do something with that particular alert

 }

}

如果要确定是否已读取特定警报,可以像这样搜索它:


Alert::where('id', '=', $alert_id)->where('read', '=', 1)->first(); 

//will return alert or null


查看完整回答
反对 回复 2022-06-11
  • 2 回答
  • 0 关注
  • 113 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信