はじめに
AuthServiceProvider
内でテーブルのデータを扱う処理を書いていました。
それが原因でちょっとしたエラーに遭遇したので、残しておこうと思います。
エラーの発生状況
以下のように、AuthServiceProvider
内でShop::all()
を使って動的にGateを定義していました。
use App\Models\Shop;
use Illuminate\Support\Facades\Gate;
use App\Models\Admin;
public function boot()
{
foreach (Shop::all() as $shop) {
// 「shop-[店舗ID]」で店舗権限を実装
Gate::define('shop-' . $shop->id, function (Admin $admin) use ($shop) {
return $admin->hasShopAuth($shop->id);
});
}
}
検証環境にソースをデプロイし、php artisan migrate
を実行。
すると以下のエラーが発生。
Illuminate\Database\QueryException
SQLSTATE[42S02]: Base table or view not found: 1146 Table 'bside_database.shops' doesn't exist (Connection: mysql, SQL: select * from `shops`)
原因
問題なのはShop::all()
でした。
artisanコマンドの実行時には、AuthServiceProvider::boot()が呼ばれます。
php artisan migrate
の実行時にAuthServiceProvider::boot()
が呼ばれて、まだshops
テーブルが存在しない状態でShop::all()
を実行してしまうことが原因でした。
自分の環境では既にshops
テーブルが存在したので事象は起きなかったのですが、検証環境でphp artisan migrate
の実行時に発覚しました。
解決策
テーブルが存在する場合のみShop::all()
を実行するように、Schema::hasTable()
で判定を追加しました。
use Illuminate\Support\Facades\Schema;
public function boot()
{
if (Schema::hasTable('shops')) {
foreach (Shop::all() as $shop) {
// 「shop-[店舗ID]」で店舗権限を実装
Gate::define('shop-' . $shop->id, function (Admin $admin) use ($shop) {
return $admin->hasShopAuth($shop->id);
});
}
}
}
まとめ
LaravelのAuthServiceProvider
内でテーブルのデータを使う場合は、Schema::hasTable()
でテーブルの存在確認を行う。
告知
最後にお知らせとなりますが、イーディーエーでは一緒に働くエンジニアを
募集しております。詳しくは採用情報ページをご確認ください。
みなさまからのご応募をお待ちしております。