--- tags: PHP, Laravel, Backend --- # laravel notification database 連接到其他資料庫 ## 問題如下 環境: laravel7 User的model是連接到A資料庫,notification要連接到B資料庫,但因為User model連接到A表所以他會去找A資料庫底下的notification資料表,導致錯誤 ## 如何解決 覆蓋掉原先包裡面程式碼,我將覆蓋的程式碼放在`App\Overrides\Notifications`裡面,你也可以自行定義,但要記得更改`namespace` 創建一個`Notifiable.php`,這個檔案要覆蓋掉在User Model裡使用的`Notifiable` ```php= <?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= <?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= <?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= <?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,將`Notifiable`更改成剛剛創建的檔案,就大功告成囉 ```php= <?php use App\Overrides\Notifications\Notifiable; class User extends Model { use Notifiable; protected $connection = 'A資料庫'; } ``` [參考stackoverflow](https://stackoverflow.com/questions/41521255/laravel-change-connection-for-notifications-table)