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

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

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

２、１から自分で作る

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

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

１、通知データを格納するテーブルを作成
※今回は、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テーブルが作られる

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

```
php artisan make:notification 名前
```

今回は例として

```
php artisan make:notification InvoicePaid
```
を作成します。

３、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の機能をとるかという、わけのわからん２択を迫られる。
どうやっても解決できそうになく

それで結局私が行なった手段は
**１から自分で作る＼(^o^)／**


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