You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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() 验证是正常的。

核心问题根源

  1. 批量赋值规则冲突:租户模型同时定义了 $guarded 和 $fillable,Laravel 不建议同时使用这两个属性,导致表单提交的字段无法被正确填充到模型。
  2. 主键 ID 缺失生成逻辑:租户表主键为字符串类型,但创建时未传入或生成唯一 ID,干扰了模型的正常创建流程。
  3. 字段传递未过滤:控制器直接将包含 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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.09 00:40:18