Laravel:具有多对多关系的历史排名系统
Posted
技术标签:
【中文标题】Laravel:具有多对多关系的历史排名系统【英文标题】:Laravel: Historical ranking system with ManyToMany relationship 【发布时间】:2016-06-13 21:30:52 【问题描述】:我想显示一个按排名列出用户的页面。一个排名可以有多个用户(例如,2 个用户可以排在第二位),一个用户也可以有多个排名,因为我想保留用户和排名的历史记录。
这里是User.php
namespace App;
use Illuminate\Foundation\Auth\User as Authenticatable;
class User extends Authenticatable
// ...
public function Ranks()
return $this->belongsToMany('App\Rank');
还有Rank.php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Rank extends Model
public $timestamps = false;
public function Users()
return $this->belongsToMany('App\User')->withPivot('created_at');
我的数据库中还有一个rank_user
表,其中包含id
、rank_id
、user_id
和created_at
字段。
这是我在数据库中记录的方式:
$user->ranks()->attach($rank_id, ['created_at' => Carbon::now()->addMinutes(105)]);
为了按排名列出用户,我的意思是在当前(最近)排名,这就是我所拥有的:
$ranks = Rank::with('users')->get();
例如,对于第一名,它给我所有从一开始就排在第一位的用户,而不是给我所有当前排在第一位的用户。
我不知道如何将查询限制为最近的日期。
【问题讨论】:
假设用户获得了排名 1,但之后一年没有玩游戏。他们是否还应该与最近获得 1 级的其他 1 级的人一起返回? hmm,你需要得到所有等级,使用 created_at 的每个用户的最后一条记录,我到现在都找不到正确的代码,这真是一个有趣的问题 试试这个$rank = App\Rank::with(['users' => function ($query) $query->latest(); ])->get();
@Samsquanch:即使用户一年不玩游戏,也会在rank_user
表中插入一条新记录,其中包含今天的日期。因此,如果有人比第一个一年没有上场的球员得分多,他就会击败他。 @AchrafKhouadja:您的代码不起作用,因为它列出了所有已经获得第一名、第二名等的用户...在下面查看我的答案:)
【参考方案1】:
我问了我的一位朋友,这是我们找到的解决方案:
我首先必须将最近的日期包含在 rank_user
数据透视表中。
$date = DB::table('rank_user')->select('created_at')
->orderBy('created_at', 'desc')
->first();
然后,我可以使用withPivot()
指定我只想要我们之前找到的最近日期的结果:
$ranks = Rank::with(['users' => function($query) use ($date)
$query->wherePivot('created_at', $date->created_at);
])->get();
瞧!这样,我只能获取每个排名中最近的用户。
【讨论】:
以上是关于Laravel:具有多对多关系的历史排名系统的主要内容,如果未能解决你的问题,请参考以下文章