laravel notification table 連接到其他資料庫

問題如下

環境: laravel7

User 的 model 是連接到 A 資料庫,notification 要連接到 B 資料庫,但因為 User model 連接到 A 表所以他會去找 A 資料庫底下的 notification 資料表,導致錯誤

如何解決

覆蓋掉原先包裡面程式碼,我將覆蓋的程式碼放在App\Overrides\Notifications裡面,你也可以自行定義,但要記得更改namespace

創建Notifiable.php

這個檔案要覆蓋掉在 User Model 裡使用的Notifiable

<?php

namespace App\Overrides\Notifications;

use App\Overrides\Notifications\HasDatabaseNotifications;
use Illuminate\Notifications\RoutesNotifications;

trait Notifiable
{
use HasDatabaseNotifications, RoutesNotifications;
}

創建DatabaseNotification.php

這是要覆蓋掉原先的 notification 的 model,加上protected $connection = '';就可以連接到自定義的資料庫

<?php

namespace App\Overrides\Notifications;

use Illuminate\Database\Eloquent\Model;

class DatabaseNotification extends Model
{
protected $connection = 'B資料庫';
/**
* The "type" of the primary key ID.
*
* @var string
*/
protected $keyType = 'string';

/**
* Indicates if the IDs are auto-incrementing.
*
* @var bool
*/
public $incrementing = false;

/**
* The table associated with the model.
*
* @var string
*/
protected $table = 'notifications';

/**
* The guarded attributes on the model.
*
* @var array
*/
protected $guarded = [];

/**
* The attributes that should be cast to native types.
*
* @var array
*/
protected $casts = [
'data' => 'array',
'read_at' => 'datetime',
];

/**
* Get the notifiable entity that the notification belongs to.
*
* @return \Illuminate\Database\Eloquent\Relations\MorphTo
*/
public function notifiable()
{
return $this->morphTo();
}

/**
* Mark the notification as read.
*
* @return void
*/
public function markAsRead()
{
if (is_null($this->read_at)) {
$this->forceFill(['read_at' => $this->freshTimestamp()])->save();
}
}

/**
* Mark the notification as unread.
*
* @return void
*/
public function markAsUnread()
{
if (! is_null($this->read_at)) {
$this->forceFill(['read_at' => null])->save();
}
}

/**
* Determine if a notification has been read.
*
* @return bool
*/
public function read()
{
return $this->read_at !== null;
}

/**
* Determine if a notification has not been read.
*
* @return bool
*/
public function unread()
{
return $this->read_at === null;
}

/**
* Create a new database notification collection instance.
*
* @param array $models
* @return \Illuminate\Notifications\DatabaseNotificationCollection
*/
public function newCollection(array $models = [])
{
return new DatabaseNotificationCollection($models);
}
}

創建HasDatabaseNotifications.php

這裡的DatabaseNotification連接到的是剛剛創建的DatabaseNotification.php

<?php

namespace App\Overrides\Notifications;

trait HasDatabaseNotifications
{
/**
* Get the entity's notifications.
*
* @return \Illuminate\Database\Eloquent\Relations\MorphMany
*/
public function notifications()
{
return $this->morphMany(DatabaseNotification::class, 'notifiable')->orderBy('created_at', 'desc');
}

/**
* Get the entity's read notifications.
*
* @return \Illuminate\Database\Query\Builder
*/
public function readNotifications()
{
return $this->notifications()->whereNotNull('read_at');
}

/**
* Get the entity's unread notifications.
*
* @return \Illuminate\Database\Query\Builder
*/
public function unreadNotifications()
{
return $this->notifications()->whereNull('read_at');
}
}

創建DatabaseNotificationCollection.php

<?php

namespace App\Overrides\Notifications;

use Illuminate\Database\Eloquent\Collection;

class DatabaseNotificationCollection extends Collection
{
/**
* Mark all notifications as read.
*
* @return void
*/
public function markAsRead()
{
$this->each->markAsRead();
}

/**
* Mark all notifications as unread.
*
* @return void
*/
public function markAsUnread()
{
$this->each->markAsUnread();
}
}

更改 User Model

都創建完畢後到你自己的 User model,將Notifiable更改成剛剛創建的檔案,就大功告成囉

<?php

use App\Overrides\Notifications\Notifiable;

class User extends Model
{
use Notifiable;

protected $connection = 'A資料庫';

}