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

如何检查用户additionalInfo模型的所有属性是否已填写?

问题描述

我有一个用户的additionalInfo模型,用户填写完附加信息可获得奖励,因此需要检查该模型的所有属性是否已填写。我现在有两个疑问:

  1. 是否需要逐个检查每个属性,比如依次检查$clientAdditionalInfo['address']、$clientAdditionalInfo['city']、$clientAdditionalInfo['province']等?
  2. 或者采用如下遍历模型属性的方式是否可行?
public function isCompleted() {
    $user = auth()->user();
    
    $clientAdditionalInfo = $user->client->additionalClientInfo->where('client_id', $user->client->id)->get()->first();
    
    if($clientAdditionalInfo){
        $attributes = $clientAdditionalInfo->getAttributes();

        foreach($attributes as $attribute) {
            // 此处是否可检查每个属性是否已填写?
        }
    }
}

我原本想遍历属性,逐个检查是否isset,全部设置就判定信息已填写并发放奖励,但不知道怎么确认所有属性都已设置。而且遍历的时候发现最后多了一个null值(在updated_at之后),但数据库里这条数据的所有值都已填写,只有一行数据。循环中打印$key和$attribute的结果如下:

^ "id"
^ 1
^ "address"
^ "Calle test 123"
^ "city"
^ "Barcelona"
^ "province"
^ "Barcelona"
^ "postal_code"
^ "08010"
^ "web"
^ "https://www.test.com"
^ "phone"
^ "123456789"
^ "activity"
^ "Social"
^ "number_of_employees"
^ 150
^ "interest"
^ "Test"
^ "client_id"
^ 8
^ "created_at"
^ "2023-02-08 10:48:56"
^ "updated_at"
^ "2023-02-08 11:53:43"
^ null

这个null的来源我搞不清楚,不符合预期。后来我意识到自己的检查方式有误,应该通过$request->all()来检查,这样可以排除created_at和updated_at,检查更精准。

解决方案建议

方案1:指定必填字段列表检查

如果模型里只有部分字段是用户需要填写的(比如排除id、client_id、created_at、updated_at这些系统自动生成的字段),最稳妥的方式是定义一个必填字段数组,逐个检查这些字段是否有值:

public function isCompleted() {
    $user = auth()->user();
    $clientAdditionalInfo = $user->client->additionalClientInfo->where('client_id', $user->client->id)->first();

    if (!$clientAdditionalInfo) {
        return false;
    }

    // 定义需要用户填写的必填字段
    $requiredFields = ['address', 'city', 'province', 'postal_code', 'web', 'phone', 'activity', 'number_of_employees', 'interest'];

    foreach ($requiredFields as $field) {
        // 检查字段是否为空(注意区分空字符串、null和0这类合法值)
        if (empty($clientAdditionalInfo->{$field}) && !is_numeric($clientAdditionalInfo->{$field})) {
            return false;
        }
    }

    return true;
}

这种方式的好处是精准可控,不会被系统字段或者意外的null干扰,而且能根据业务灵活调整必填字段。

方案2:过滤模型属性后检查

如果不想手动维护必填字段列表,可以过滤掉模型中的系统字段,再检查剩余属性是否都有值:

public function isCompleted() {
    $user = auth()->user();
    $clientAdditionalInfo = $user->client->additionalClientInfo->where('client_id', $user->client->id)->first();

    if (!$clientAdditionalInfo) {
        return false;
    }

    // 获取模型属性并过滤系统字段
    $attributes = $clientAdditionalInfo->getAttributes();
    $excludeFields = ['id', 'client_id', 'created_at', 'updated_at'];
    $userFields = array_diff_key($attributes, array_flip($excludeFields));

    foreach ($userFields as $value) {
        if (empty($value) && !is_numeric($value)) {
            return false;
        }
    }

    return true;
}

关于你遇到的额外null值:这大概率是getAttributes()返回的数组末尾多了一个无键值的元素,可能是模型查询或者序列化时的小问题。用array_diff_key过滤掉系统字段后,这个多余的null会被排除,不会影响检查。

方案3:通过请求数据检查(你提到的思路)

如果是在用户提交表单的请求中做检查,可以直接用$request的验证规则,Laravel自带的验证器能帮你快速判断字段是否齐全:

// 在控制器的提交方法中
public function submitAdditionalInfo(Request $request) {
    // 定义验证规则
    $validated = $request->validate([
        'address' => 'required',
        'city' => 'required',
        'province' => 'required',
        'postal_code' => 'required',
        'web' => 'required|url',
        'phone' => 'required',
        'activity' => 'required',
        'number_of_employees' => 'required|numeric',
        'interest' => 'required',
    ]);

    // 验证通过,保存数据并发放奖励
    $user = auth()->user();
    $user->client->additionalClientInfo()->updateOrCreate(
        ['client_id' => $user->client->id],
        $validated
    );

    // 发放奖励逻辑
    // ...

    return redirect()->back()->with('success', '信息填写完成,奖励已发放');
}

这种方式在用户提交时就完成了检查,避免后续再去数据库查询验证,逻辑更顺畅,也符合Laravel的最佳实践。


内容的提问来源于stack exchange,提问作者Ignacio

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 01:13:59