Laravel Eloquent 显示后更新
Posted
技术标签:
【中文标题】Laravel Eloquent 显示后更新【英文标题】:Laravel Eloquent update after display 【发布时间】:2021-12-28 12:06:37 【问题描述】:我在使用自定义通知模型(不是 Laravel 标准模型)时遇到了问题。
在我的控制器中,我获取所有通知并将它们保存到一个变量中。
之后,我将更新所有通知并设置 read_at
日期时间。
public function index($showRead = null)
$user = auth()->user();
$notifications = $user->notifications()->latest()->paginate(10);
$view = view('notification.index',['notifications'=>$notifications])->render();
Notification::where('id_user',$user->id)->update(['read_at'=>now()]);
return $view;
问题:
$notifications
集合确实包含 read_at NULL
条目,因为我在第二行获取数据。
但不知何故,更新也会刷新渲染视图。
我能以某种方式阻止这种情况吗?我想在第一页请求上显示未读通知,在下面的请求中,它们应该有时间戳。
【问题讨论】:
可以分享一下视图刀片文件吗? 【参考方案1】:在此查询中使用where()
条件来获取未读通知:$notifications = $user->notifications()->where('read_at', Null)->orderBy('created_at', 'DESC')->paginate(10);
阅读后更新通知的解决方案:
解决方案 1:
将未读通知存储到Laravel Collections 并压缩到视图:$notifications = $user->notifications()->latest()->paginate(10);
解决方案 2:
或者在您的视图刀片中运行此查询Notification::where('id_user',$user->id)->update(['read_at'=>now()]);
解决方案 3:
当用户将访问通知视图刀片时,发送 AJax 请求以更新通知。
【讨论】:
【参考方案2】:您可以在通知上创建一个构建器(不要使用 get),然后将第一个构建器克隆到另一个变量中,之后您可以更新克隆的构建器并从原始构建器获取集合。
$notifsBuilder1= $user->notifications();
$notifsBuilder2 = clone $notifsBuilder1;
$notifs = $notifsBuilder1->latest()->paginate(10);
$notifsBuilder2->update(['read_at'=>now()])
【讨论】:
【参考方案3】:进行此类操作的最简单方法是让您的前端向您的控制器发送一个 api 请求以读取某个通知。 你可以这样做:
class NotificationsController extends Controller
public function index(Request $request, $showRead = null)
$user = auth()->user();
$notifications = Notification::where('user_id', $user->getKey())->latest()->orderBy('created_at')->paginate(10);
return view('notifications.index', compact('notifications'));
public function markAsRead(Notification $notification)
$done = $notification->forceFill(['read_at' => now()]);
return compact('done');
如果您使用的是 VueJs,那么您可以在前端内部使用它(不用担心,您也可以查找匹配的东西,如果不是):
在你的 Vue 组件内部使用 axios 库来处理请求,并为你的路由使用 ziggy 库:
let axios = require('axios');
let notifications = [];
let getNotifications = async () =>
return axios.get(route('notifications.index')).then(res =>
notifications = res.data.notifications;
);
let markNotificationAsRead = (notification_id) =>
axios.get(route('notification.read', ['notification' => notification_id]));
getNotifications();
for(let i = 0; i < notifications.length; i++)
markNotificationAsRead(notifications[notification].id);
这样,您的所有通知都是通过您的 api 和您的 api 处理的,因为成像您的用户会要求通知,但在您将他的响应交给他之前取消了请求,他实际上会错过这些。
【讨论】:
以上是关于Laravel Eloquent 显示后更新的主要内容,如果未能解决你的问题,请参考以下文章