0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Laravelのデータベース通知機能について手を出してみた。

Posted at

#データベース通知とは
webアプリケーションを利用するユーザーに対し、管理者から通知を飛ばすことができる。
その通知を飛ばす手段として、メール、Slackなど様々あるが、今回は、webアプリ上に通知を出す「データベース通知
」について語っていく。

##データベース通知の実装について
データベース通知を実装について手段が2つある。
1、Laravelに標準搭載されてるnotificationを利用する。

2、1から自分で作る

ここで、私は迷わず1を選択した。(ここで1を選択した自分を後から後悔するとは誰も知る由はなかった)

###Laravelに標準搭載されてるnotificationの利用手順(これをやるかどうかは最後まで読んで決めてください)
こちらを見る前に事前知識として、こちらの記事を見ることをお勧めします。
「Laravel Notification をやさしく解説する」
https://qiita.com/ikasama/items/de7c5aa8c6056b79adf3

1、通知データを格納するテーブルを作成
※今回は、usersテーブルとcontentsテーブルが作成されている前提で進める

php artisan notifications:table

作られたマイグレーションファイル

    public function up()
    {
        Schema::create('notifications', function (Blueprint $table) {
            $table->id();
            $table->string('type');
            $table->morphs('notifiable');
            $table->text('data');
            $table->timestamp('read_at')->nullable();

            //通知データを表示させる際に表示させたいデータが格納されているテーブルの外部成約キーを持たせる
            $table->foreignId('content_id')->constrained();

            $table->timestamps();
        });
    }
php artisan migrate

これでテーブルnotificationsテーブルが作られる

2、通知データを受け取るNotificationの作成

php artisan make:notification 名前

今回は例として

php artisan make:notification InvoicePaid

を作成します。

3、Notification(InvoicePaid)の編集

class InvoicePaid extends Notification
{
    use Queueable;
    

    /**
     * Create a new notification instance.
     *
     * @return void
     */
    //コントローラーから飛んできたデータを格納する
    public function __construct($reservation,$content)
    {
        //コントローラから飛んでくる$user
        $this->reservation = $reservation;

        //コントローラから飛んでくる$content
        $this->content = $content;

    }
    /**
     * Get the notification's delivery channels.
     *
     * @param  mixed  $notifiable
     * @return array
     */
    public function via($notifiable)
    {
     //これはテンプレートなので、気にせずコピペ
        return [\Illuminate\Notifications\Channels\DatabaseChannel::class];
    }
    /**
     * Get the mail representation of the notification.
     *
     * @param  mixed  $notifiable
     * @return \Illuminate\Notifications\Messages\MailMessage
     */
    //これは利用しないのでコメントアウト
    // public function toMail($notifiable)
    // {
    //     return (new MailMessage)
    //                 ->line('The introduction to the notification.')
    //                 ->action('Notification Action', url('/'))
    //                 ->line('Thank you for using our application!');
    // }
    /**
     * Get the array representation of the notification.
     *
     * @param  mixed  $notifiable
     * @return array
     */
   //これはdataカラムに入れるデータを入れる。入れるものがなければ空欄でOK
    public function toArray($notifiable)
    {
        return [
            //
        ];
    }
}

4、コントローラーに通知データを作成する関数の設置

use App\Notifications\InvoicePaid;
use App\Models\User;
use App\Models\Content;
use App\Models\Notification;

(略)

public function index()
    {
        //通知を与えたいユーザーデータを入れる
        $user = User::find(該当するid);

     //通知データが保管されるレコードに保存したいデータを入れる
        $content = Content::find(該当するid);

     $user->notify(new InvoicePaid($user,$content));

        return view('index')->with([
                        'user' => $user,
                        'contents' => $contents,
                        ]);;
    }

(略)

5、DatabaseChannelの編集。ここで、通知データに格納するデータの設定をする

(略)
class DatabaseChannel
{
    (略)
    protected function buildPayload($notifiable, Notification $notification)
    {
        return [
             //カラムに対して格納したいデータを入れる
            'id' => $notification->id,
            'type' => get_class($notification),
            'data' => $this->getData($notifiable, $notification),
            'read_at' => null,

        //InvoicePaidの__constructからデータが飛んでくる
            'content_id' => $content->id,
        ];
    }
}

6、これで設定は完了。このあと、indexメソッドを利用をすれば、notificationsテーブルにレコードが追加される。

 が…ここから試練が訪れる…!!!!!
 その名も「リレーションできない事件

 notificationsテーブルと他テーブルをHasmany⇄belong to の関係を持たせると、

  $user->notify(new InvoicePaid($user,$content))

これが発火しなくなり、notificationsテーブルにデータを入れれないようになる。
そのため、リレーションをとるか、notifyの機能をとるかという、わけのわからん2択を迫られる。
どうやっても解決できそうになく

それで結局私が行なった手段は
1から自分で作る\(^o^)/

やってから気づいたけど、notifyをドキュメント読んで理解するより、自分で作った方が断然早い。笑

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?