Stancl/Tenancy 新租户创建时如何自动运行对应迁移文件?
Stancl/Tenancy 租户创建自动执行迁移解决方案
Stancl/Tenancy 默认不会在租户创建后自动执行迁移,你可以通过以下两种方式实现需求:
方案1:事件监听自动执行(推荐,解耦性好)
- 首先在
app/Providers/EventServiceProvider.php的$listen数组中注册事件映射:
protected $listen = [ \Stancl\Tenancy\Events\TenantCreated::class => [ \App\Listeners\RunTenantMigration::class, ], ];
- 执行命令生成监听器:
php artisan make:listener RunTenantMigration,编写监听器逻辑:
<?php namespace App\Listeners; use Stancl\Tenancy\Events\TenantCreated; use Illuminate\Support\Facades\Artisan; class RunTenantMigration { public function handle(TenantCreated $event) { // 迁移量少可直接同步执行 Artisan::call('tenants:migrate', [ '--tenant' => $event->tenant->id, ]); // 迁移量大避免请求阻塞,可改用队列异步执行 // Artisan::queue('tenants:migrate', [ // '--tenant' => $event->tenant->id, // ]); } }
配置完成后只要创建新租户就会自动触发对应迁移,不需要在控制器中重复编写逻辑。
方案2:直接在控制器中手动调用
如果你不想用事件监听,也可以直接在创建租户的逻辑后追加迁移执行代码。同时你原有代码中的闭包没有引入$request变量会报错,修正后的完整控制器代码如下:
public function store(Request $request) { $this->validate($request, [ 'company' => 'required', 'domain' => 'required|unique:domains', 'name' => 'required', 'email' => 'required|unique:users,email', 'password' => 'required|confirm' ]); $tenant_id = '-' . Str::slug($request->company, '-'); $domain = $request->domain . '.' . 'saas.test'; $tenant = Tenant::create([ 'id' => $tenant_id ]); // 执行当前租户的迁移 \Illuminate\Support\Facades\Artisan::call('tenants:migrate', [ '--tenant' => $tenant->id, ]); $tenant->createDomain([ 'domain' => $domain ]); // 闭包引入$request变量 $tenant->run(function() use ($request) { User::create([ 'name' => $request->name, 'email' => $request->email, 'password' => bcrypt($request->password) ]); }); tenancy()->initialize($tenant); return redirect($domain); }
关于是否需要后台运行的说明
如果你的租户迁移文件少、执行速度快,同步执行完全没问题。如果迁移逻辑复杂、执行时间长,建议把迁移命令丢到队列中异步执行,避免用户创建租户时请求超时。
内容的提问来源于stack exchange,提问作者Exploit
相关产品推荐
相关产品推荐

