#データベース通知とは
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をドキュメント読んで理解するより、自分で作った方が断然早い。笑