Laravel 5.5 - 如何查询带有 created_at 时间戳的关注者的通知?
Laravel 5.5 - How to query notifications for follower with created_at timestamp?
用户可以是追随者 and/or 领导者。这里 userA 和 userB(都是领导者)在不同时间被 userC(追随者)跟随(请参阅下面的 followers
table created_at
时间戳)。
为了说明问题,我先排一下模板:
userX action (year) // template to understand issue below
userC followed userA (2016)
userA added postA/notification (2017)
userC should get notification in feed, since they followed userA a year BEFORE their post
userB added postB/notification (2018)
userC followed userB (2019)
userC should NOT get notification in feed, since they followed userB a year AFTER their post
为此,我尝试了这个查询,但它无法正常工作:
$user = App\User::find(3); // follower
$leaders = $user->leaders()
->with(['leaderNotifications'=>function($query){
$query->where('notifications.created_at','>','followers.created_at');
}])
->get();
我认为这个问题与 created_at
没有被正确查询有关。这是在本地查看的确切设置:
1) DB table name/data
users
followers
notifications
2) 型号
// User
<?php
namespace App;
use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\DatabaseNotification;
use Illuminate\Notifications\DatabaseNotificationCollection;
class User extends Authenticatable {
use Notifiable;
// Pivot Table
public function leaders() {
return $this->belongsToMany('App\User', ‘followers’, 'follower_id', 'leader_id')
->withPivot('created_at'); // need timestamp to compare against notification timestamp
}
public function leaderNotifications() {
return $this->hasMany(DatabaseNotification::class, 'leader_id')
->orderBy('created_at', 'desc');
}
}
我正在尝试获取当前关注者 userC
的正确通知,这意味着只有他们关注领导者 之后 的新通知,而不是领导者的旧通知 before 他们被当前用户关注了。
还值得注意的是,最终查询应该能够一次 paginate->(20)
这些通知,因为它将用一百万行进行测试,所以我们需要确保它是 efficient/scalable 并且可以分页。
这个问题的 efficient/scalable 查询是什么?
1) For raw query in Laravel you should using whereRaw
.
2) When using with()
, Laravel get data in two query , first
get result of parent query and then using result for getting with()
,
If you want to use pivot columns of first query in with
closure,you can
join.
试试这个:
$user = App\User::find(3); // follower
$leaders = $user
->leaders()
->with(['leaderNotifications'=>function($query) use ($user){
$query->whereRaw('notifications.created_at > followers.created_at')
->join('followers','followers.leader_id','=','notifications.leader_id')
->where('followers.follower_id',$user['id']);
}])
->get();
以下是我的解决方法以防对其他人有帮助:
$user = App\User::find(3); // follower
$leaders = DB::table('notifications')
->join('followers','followers.leader_id','=','notifications.leader_id')
->where('followers.follower_id', $user->id)
->whereRaw('notifications.created_at > followers.created_at')
->paginate(20);
无需预先加载或使其更加复杂。只需一个简单的 DB
查询即可处理!
用户可以是追随者 and/or 领导者。这里 userA 和 userB(都是领导者)在不同时间被 userC(追随者)跟随(请参阅下面的 followers
table created_at
时间戳)。
为了说明问题,我先排一下模板:
userX action (year) // template to understand issue below
userC followed userA (2016)
userA added postA/notification (2017)
userC should get notification in feed, since they followed userA a year BEFORE their post
userB added postB/notification (2018)
userC followed userB (2019)
userC should NOT get notification in feed, since they followed userB a year AFTER their post
为此,我尝试了这个查询,但它无法正常工作:
$user = App\User::find(3); // follower
$leaders = $user->leaders()
->with(['leaderNotifications'=>function($query){
$query->where('notifications.created_at','>','followers.created_at');
}])
->get();
我认为这个问题与 created_at
没有被正确查询有关。这是在本地查看的确切设置:
1) DB table name/data
users
followers
notifications
2) 型号
// User
<?php
namespace App;
use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\DatabaseNotification;
use Illuminate\Notifications\DatabaseNotificationCollection;
class User extends Authenticatable {
use Notifiable;
// Pivot Table
public function leaders() {
return $this->belongsToMany('App\User', ‘followers’, 'follower_id', 'leader_id')
->withPivot('created_at'); // need timestamp to compare against notification timestamp
}
public function leaderNotifications() {
return $this->hasMany(DatabaseNotification::class, 'leader_id')
->orderBy('created_at', 'desc');
}
}
我正在尝试获取当前关注者 userC
的正确通知,这意味着只有他们关注领导者 之后 的新通知,而不是领导者的旧通知 before 他们被当前用户关注了。
还值得注意的是,最终查询应该能够一次 paginate->(20)
这些通知,因为它将用一百万行进行测试,所以我们需要确保它是 efficient/scalable 并且可以分页。
这个问题的 efficient/scalable 查询是什么?
1) For raw query in Laravel you should using
whereRaw
.2) When using
with()
, Laravel get data in two query , first get result of parent query and then using result for gettingwith()
, If you want to use pivot columns of first query inwith
closure,you can join.
试试这个:
$user = App\User::find(3); // follower
$leaders = $user
->leaders()
->with(['leaderNotifications'=>function($query) use ($user){
$query->whereRaw('notifications.created_at > followers.created_at')
->join('followers','followers.leader_id','=','notifications.leader_id')
->where('followers.follower_id',$user['id']);
}])
->get();
以下是我的解决方法以防对其他人有帮助:
$user = App\User::find(3); // follower
$leaders = DB::table('notifications')
->join('followers','followers.leader_id','=','notifications.leader_id')
->where('followers.follower_id', $user->id)
->whereRaw('notifications.created_at > followers.created_at')
->paginate(20);
无需预先加载或使其更加复杂。只需一个简单的 DB
查询即可处理!