---
# System prepended metadata

title: laravel notification database 連接到其他資料庫
tags: [PHP, ' Backend', ' Laravel']

---

---
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)

