В базу. Пользователь создаёт тему, эту тему комментит другой пользователь, и пользователю, который создал эту тему, приходит уведомление, что на его тему, кто-то оставил коммент. В правильном ли направлении я вообще двигаюсь? Нотофикация PHP: <?php namespace App\Notifications; use Illuminate\Bus\Queueable; use Illuminate\Notifications\Notification; use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Notifications\Messages\MailMessage; class MyFirstNotification extends Notification { use Queueable; private $details; public function __construct($details) { $this->details = $details; } public function via($notifiable) { return ['database']; } public function toDatabase($notifiable) { return [ 'user_id' => $this->details['user_id'], 'comment_id' => $this->details['comment_id'] ]; } } Контроллер PHP: public function sendNotification() { //здесь будет id юзера, который создал тему $user = User::find(1); //user_id - тот кто ответил //comment_id - id коммента $details = [ 'user_id' => Auth::id(), 'comment_id' => 5, ]; Notification::send($user, new MyFirstNotification($details)); dd('done'); } //этот метод для того, что бы //пользователю показать его уведомления public function readNotification() { //здесь будет Auth::id() //это для примера $user = User::find(1); foreach ($user->unreadNotifications as $notification) { dump($notification->data); } die; }
Ну да. А что тут сложного-то? Уведомления в базу - это надо просто переписать то, что написано в доке. Я ещё понимаю, если бы ты спрашивал про броадкастинг - там действительно, ноду поставить, LaravelEcho поднять, я ещё проксирую его через nginx - тоже, в принципе, не так сложно, и дока есть, и статьи в нете, не сложно, но, скажем так, слегка заморочно. А уведомления в базу - Laravel всё сам за тебя делает
Слушай, отношения пользователь-уведомления - это обычные один-ко-многим, всё, о чём тут разговаривать. Просто Laravel дал несколько более удобную оболочку для этого всего
Вывожу уведомления. В таблицу notifications в дату добавляются данные, таким способом PHP: public function toDatabase($notifiable) { return [ 'post_id' => $this->details['post_id'], // id поста 'comment_id' => $this->details['comment_id'], //id комента 'user_comment_id' => $this->details['user_comment_id'] // id юзера, который оставил коммент ]; Теперь мне надо вывести список уведомлений, что бы было видно, кто оставил комент, и на какой пост, сделал это так PHP: public function readNotification() { $user = User::find(Auth::id()); $allData = collect(); foreach ($user->unreadNotifications as $notification) { $collect1 = collect(Post::find($notification->data['post_id'])); $collect2 = collect(['user_comment' => Comment::find($notification->data['comment_id'])->text]); $collect3 = collect(['user_name' => User::find($notification->data['user_comment_id'])->name]); $allData->push($collect1 ->merge($collect2) ->merge($collect3) ->merge(['id_notif' => $notification->id])); } return view('read-notifications', [ 'allData' => $allData, ]); } HTML: <section class="section main-content"> <div class="container"> @foreach ($allData as $data) <div class="card"> <div class="card-body"> <h5 class="card-title">{{$data['user_name']}}, добавил комментраий к посту - {{$data['description']}}</h5> <div class="card-text">{!!$data['user_comment']!!}</div> <br> <a href="/post/{{$data['id']}}" class="btn btn-primary">Перейти</a> <a href="/mark-notif-read/{{$data['id_notif']}}" class="btn btn-primary">Отменить прочитанным</a> </div> </div> <br> @endforeach </div> </section> Это нормальный способ? Какой есть по лучше?
Ты бы мог использовать стену своего профиля для ведения блога "Что сейчас ковыряет Димон". Походу ты чемпион по темам!
Попробуй самостоятельно убрать запросы в цикле. Ты же в курсе, что не хорошо? Коллекции здесь не пойми зачем, обычным массивом тоже самое было бы сделать проще и красивее.
@Dimon2x, у тебя не три запроса, а 3 * на кол-во уведомлений (это если там ещё with-ов нет внутри). Вот сделай, чтоб было просто 3
Ну вот возьми и подумай, как эти запросы можно вынести из цикла. У тебя запросы внутри цикла. Их можно оттуда вынести. Я бы конечно вообще один вызов find сделал, и хранил бы только comment_id в уведомлении, а пост и комментатора получал по связям и with(), но давай по очереди
Вот так сделал PHP: $user = User::find(Auth::id()); foreach ($user->unreadNotifications as $notification) { $aaa = Comment::with('post) ->with('users') ->where('post_id', $notification->data['post_id']) ->where('user_id', $notification->data['user_comment_id']) ->where('id', $notification->data['comment_id']) ->get(); dump($aaa); }
Уже лучше. Но можно вынести из цикла, надо немного сообразительность проявить. Ты же не салага уже, думай
@Dimon2x, запросов не меньше, но код выглядит лучше @Dimon2x, я тебе уже третий раз говорю - вынеси запросы из цикла, а ты их пишешь внутри цикла. Оно работать так будет, как ты написал, но ты же сам спрашиваешь, как лучше
Дока не заменяет мозг Тут нужно напрячь мозг, вспомнить, что у нас SQL в итоге получается, вспомнить, зачем нам Query Builder и прочее. Больше механизмов Laravel-я задействовано.
@mkramer всё равно, что бы добавить id уведомления, надо использовать коллекции PHP: $user = User::find(Auth::id()); $aaa = collect(); foreach ($user->unreadNotifications as $notification) { $collect1 = collect(Comment::with('question') ->with('users') ->where('post_id', $notification->data['post_id']) ->where('user_id', $notification->data['user_comment_id']) ->where('id', $notification->data['comment_id']) ->get()); $aaa->push($collect1 ->merge(['id_notif' => $notification->id])); }
Коробочный компонент уведомлений. Когда комментишь статью, то приходят уведомления, и они помечаются прочитанными, как сделать, что бы при удалении статьи, из таблицы удалялись эти уведомления? Ведь в таблицу не записывается отдельный id статьи, а записывается всё в столбец data. Может раширить таблицу уведомлений и добавить отдельный столбец id поста? Или есть уже готовое решение? Ведь взять все записи и перебрать каждую, потом искать есть ли в этом объекте id поста, это будет слишком большая нагрузка и это не логично.
@mkramer mysql 5.7 --- Добавлено --- Нашёл этот чудесный способ PHP: $notifications = DB::table('notifications') ->whereJsonContains('data->post_id', $id) ->get(); dd($notifications);
@mkramer вот так сделал, допустимо ли? PHP: $notifications = array_keys(DB::table('notifications')->select('id') ->whereJsonContains('data->post_id', $id) ->get()->groupBy('id')->toArray()); DB::table('notifications')->whereIn('id', $notifications)->delete(); --- Добавлено --- Так мне больше нравится PHP: $notifications = DB::table('notifications')->select('id') ->whereJsonContains('data->post_id', $id) ->get()->pluck('id')->toArray();
@Dimon2x, да, допустимо. Поэтому я и спросил про версию СУБД. MySQL научилась ладить с JSON только в 5.7. Хорошее решение