在 Laravel 5.3 的通知中,如何将特定的通知标记为已读?

15

我知道在L5.3中有很多方法可以标记所有用户通知为已读,例如:

$user = App\User::find(1);

foreach ($user->unreadNotifications as $notification) {
    $notification->markAsRead();
}

或者:

$user->unreadNotifications->markAsRead();

但是假设我想要标记一个特定ID的通知为已读。

实际上,我已经按照以下方式列出了未读用户通知:

<ul class="menu">
        @foreach($AuthUser->unreadNotifications as $notif)
            <li>
                <a href="{{$notif->data['action']}}" data-notif-id="{{$notif->id}}">
                    {{$notif->data['message']}}
                </a>
            </li>
        @endforeach
</ul>

正如您所看到的,每个a标签都有一个包含通知ID的data-notif-id属性。

现在我想通过Ajax将此ID发送到脚本(在单击事件中),并仅将该通知标记为已读。为此,我编写了以下代码:

$('a[data-notif-id]').click(function () {

        var notif_id   = $(this).data('notifId');
        var targetHref = $(this).data('href');

        $.post('/NotifMarkAsRead', {'notif_id': notif_id}, function (data) {
            data.success ? (window.location.href = targetHref) : false;
        }, 'json');

        return false;
});

NotifMarkAsRead 指的是以下控制器:

class NotificationController extends Controller
    {
        public function MarkAsRead (Request $request)
        {
              //What Do I do Here........
        }
    }

如果没有任何Notification模型,我该如何做到这一点?


如果没有 Notification 模型(因此没有关系集),那么 unreadNotifications 方法来自哪里?或者说:它是什么?一个自定义方法吗? - lesssugar
Illuminate\Notifications\Notifiable特性提供了一个markAsRead方法,我在User Model中使用了它。 - Ahmad Badpey
unreadNotifications() 返回一个模型,因此您可以使用链接来过滤,例如:$user->unreadNotifications()->where('notifications.id', $id)->markAsRead();。或者,如果 markAsRead() 方法不可用,我也会尝试使用 ->update(['read_at' => Carbon::now()]) 来代替。 - lesssugar
6个回答

15
根据Github上的这个回答,解决方案是:

Illuminate\Notifications\DatabaseNotification 是通知模型所在的地方,您可以使用它通过ID获取通知并删除它。此外,如果您不想使用该模型,则可以使用普通的DB查询。


1
这正是我一直在寻找的答案。感谢您提供的模型地址。 - Amit Shah

14

这个绝对可行:

$id = auth()->user()->unreadNotifications[0]->id;
auth()->user()->unreadNotifications->where('id', $id)->markAsRead();

虽然这段代码可能解决了OP的问题,但最好还是解释一下你的代码如何解决OP的问题。这样,未来的访问者可以从您的帖子中学习,并将其应用到自己的代码中。SO不是编码服务,而是知识资源。此外,高质量、完整的答案更有可能被点赞。这些特点以及所有帖子都必须是自包含的要求,是SO作为一个平台的一些优势,使其与论坛区分开来。您可以编辑以添加其他信息和/或使用源文档补充您的解释。 - SherylHohman
1
如果通知来自多个模型,则此方法无效。您假设所有通知都是用户通知,但通知可以从任何模型生成。 - Leon

6
$notification = auth()->user()->notifications()->find($notificationid);
if($notification) {
    $notification->markAsRead();
}

虽然这段代码可能解决了OP的问题,但最好还是解释一下你的代码如何解决OP的问题。这样,未来的访问者可以从您的帖子中学习,并将其应用到自己的代码中。SO不是编码服务,而是知识资源。此外,高质量、完整的答案更有可能被点赞。这些特点以及所有帖子都必须是自包含的要求,是SO作为一个平台的一些优势,使其与论坛区分开来。您可以编辑以添加其他信息和/或使用源文档补充您的解释。 - SherylHohman
如果通知来自多个模型,则此方法无效。您假设所有通知都是用户通知,但通知可以从任何模型生成。因此,原帖询问直接访问通知,而不是通过用户模型访问。 - Leon

1

首先,您必须确保通知存在,以便对其进行调整。我不建议使用未读通知对象,因为如果没有未读通知,会发生错误。

$notification_id = "03fac369-2f41-43d0-bccb-e364aa645f8a";
$Notification = Auth::user()->Notifications->find($notification_id);
if($Notification){
   $Notification->markAsRead();
}

或者你可以直接编辑,不需要任何检查。
DB::table('notifications')->where('id',$notification_id)->update(['read_at'=>Carbon::now()])

3
仅有代码的答案通常可以通过添加一些解释来改进其工作原理和原因。 - Jason Aller
虽然这段代码可以解决OP的问题,但最好还是说明一下你的代码如何解决OP的问题。这样,未来的访问者可以从您的帖子中学习,并将其应用到自己的代码中。SO不是编程服务,而是知识资源。另外,高质量、完整的答案更有可能被赞同。这些特点,以及要求所有帖子都是自包含的,是SO作为一个平台的优势之一,与论坛有所不同。您可以编辑添加其他信息和/或使用源文档补充您的解释。 - SherylHohman

0

这种方法对我来说很有效:

$unreadNotifications = Auth::user()->unreadNotifications()->whereIn('id', $items)->get();

$items是通知ID的数组!


-3

改为以下内容:

$user->unreadNotifications->markAsRead(); 

让我们使用:

$user->unreadNotifications->first()->markAsRead();

虽然这种方法允许将一个未读通知标记为已读,但它并不能真正让你控制是哪个通知。使用firstWhere或上述任何解决方案都是更好的选择。 - Mike

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接