Laravel8多租户应用创建租户时字段值无法正常插入数据库问题
Laravel 8 + Stancl Tenancy 租户创建字段填充问题解决
问题现象
使用 Laravel 8 结合 laravel/breeze 和 stancl/tenancy 构建多租户应用时,创建租户出现 SQLSTATE[HY000]: General error: 1364 Field 'name' doesn't have a default value 错误;设置字段默认值、允许空值或关闭数据库严格模式后,虽无报错但租户表插入空值,而表单提交数据经 dd() 验证是正常的。
核心问题根源
- 批量赋值规则冲突:租户模型同时定义了
$guarded和$fillable,Laravel 不建议同时使用这两个属性,导致表单提交的字段无法被正确填充到模型。 - 主键 ID 缺失生成逻辑:租户表主键为字符串类型,但创建时未传入或生成唯一 ID,干扰了模型的正常创建流程。
- 字段传递未过滤:控制器直接将包含
domain_name(属于 domains 表)的验证数据传入租户创建方法,可能引发字段匹配问题。
分步解决方案
1. 修正租户模型的批量赋值与主键逻辑
移除冲突的 $fillable,保留 $guarded 并添加主键自动生成逻辑:
use Illuminate\Support\Str; class Tenant extends BaseTenant implements TenantWithDatabase { use HasDatabase, HasDomains; // 仅保护主键ID,其余字段允许批量赋值 protected $guarded = ['id']; // 自动生成UUID作为租户ID public static function boot() { parent::boot(); static::creating(function ($tenant) { if (empty($tenant->id)) { $tenant->id = Str::uuid()->toString(); } }); } // 密码加密修改器(无需返回值) public function setPasswordAttribute($value){ $this->attributes['password'] = bcrypt($value); } }
2. 修正控制器的租户创建逻辑
过滤掉不属于租户表的字段,仅传递租户模型需要的数据:
public function store(Request $request) { $validatedData = $request->validate([ 'name' => 'required|string|max:255', 'email' => 'required|email|max:255', 'domain_name' => 'required|string|max:255|unique:domains,domain', 'password' => ['required', 'confirmed', Rules\Password::defaults()], ]); // 提取租户表所需字段,排除domain_name $tenantData = collect($validatedData)->only(['name', 'email', 'password'])->toArray(); // 创建租户 $tenant = Tenant::create($tenantData); // 关联创建域名 $tenant->domains()->create([ 'domain' => $validatedData['domain_name'] . '.' . config('app.domain') ]); return redirect()->route('tenants.index'); }
3. 恢复数据库严格模式(推荐)
之前设置 strict=false 只是临时规避问题,修复逻辑后将 config/database.php 中的 strict 改回 true,保持数据库规范。
4. 验证迁移文件正确性(可选)
确保租户表结构定义正确,若之前修改过字段规则,可重新执行迁移:
Schema::create('tenants', function (Blueprint $table) { $table->string('id')->primary(); $table->string('name'); $table->string('email'); $table->string('password'); $table->timestamps(); $table->json('data')->nullable(); });
内容的提问来源于stack exchange,提问作者Mazumder Nazmul
相关产品推荐
相关产品推荐

