【问题标题】:Laravel unique field validation issue (Duplicate entry error)Laravel 唯一字段验证问题(重复输入错误)
【发布时间】:2020-07-07 20:03:39
【问题描述】:

在我的 laravel 应用数据库中,我有一个名为 apps 的表

在该表中,我有一个列名“域”。域是一个独特的列。

问题

我的前端刀片中有一个表单供用户创建新应用程序。从该表单中,用户应首先输入子域名,然后有一个下拉菜单可以选择域名。

一旦用户输入子域名,然后选择域名,我会合并来自控制器的两个输入,然后将合并后的值保存在“域”列中。

例如: 子域名:ABC 域名:TEST.SITE 合并值(我保存在域列中的值):ABC.TEST.SITE

现在,由于我的域是唯一的,当有重复的值时,它会抛出一个 laravel 错误,说重复条目。

但是从我的控制器我无法验证子域名输入,因为最后我保存了合并的值。

解决此问题并正确进行验证的任何解决方案,

这是表单的代码。

<form id="appform" action="{{ route('app.save') }}" method="post">
                        @csrf
                            <input type="text" id="app-subdomainname" class="form-control" name="subDomainName" placeholder="{{ __('sentence.Sub Domain Name') }}" aria-required="true">
                         <br>
                            <select id="app-subdomainsuffix" class="form-control" name="subDomainSuffix" aria-required="true">
                                <option value="">- {{ __('sentence.Select domains') }} -</option>
                                <option value="TEST.SITE">TEST.SITE</option>
                            </select>

                        <br>

                        <select id="app-packagetype" class="form-control" name="packageType" aria-required="true">
                            <option value="">- {{ __('sentence.Select package type') }} -</option>
                            @foreach($packages as $package)
                            <option value="{{$package->id}}">{{$package->name}}</option>
                                @endforeach
                        </select>

                        <br>
                            <select id="app-payment" class="form-control" name="paymentoption" aria-required="true">
                            </select>

                        <br>

                            <select id="app-themeid" class="form-control" name="themeid" aria-required="true">
                                <option value="">- {{ __('sentence.Select theme') }} -</option>
                                <option value="default">Starter</option>
                            </select>

                        <br>
                            <select id="app-lang" class="form-control" name="lang" aria-required="true">
                                <option value="">- {{ __('sentence.Select Language') }} -</option>
                                <option value="en">English</option>
                                <option value="jp">Japanese</option>
                            </select>
                        <br>

                        <div class="form-group">
                            <button type="submit" class="btn btn-success">{{ __('sentence.Save') }}</button>
                        </div>

                    </form>  

我的控制器(仅包含数据存储功能)

$this->validate($request, [
            'subDomainName' => 'required',
            'subDomainSuffix' => 'required',
            //'package_type' => 'required',
            'lang' => 'required',
            'theme' => 'required',
            'paymentoption' => 'required',

        ]);

        $user = Auth::user();
        $fullDomain = $request->subDomainName.'.'.$request->subDomainSuffix;
        $credentials = $this->generateDbcredentials();
        App::create([
            'domain' => $fullDomain,
            'masterUserId' => $user->id,
            'dbName' => $credentials[0],
            'host' =>env('DB_HOST', '127.0.0.1'),
            'username' => $credentials[1],
            'password' => $credentials[2],
            'theme' => $request->themeid,
            'lang' =>  $request->lang,
            'status' => 1,
            'package_type' => $request->packageType,
            'payment_option' => $request->paymentoption,
            'isAppCreated' => 1,
            'isDefault' =>0,
        ]);

如何正确进行验证

谢谢。

【问题讨论】:

  • 您可以使用隐藏字段来组合前端的输入并发送已连接的域文件,而不是合并后端的输入吗?然后验证该值将是微不足道的
  • 另一种选择是在验证发生之前使用中间件将两个值组合到“域”输入变量中
  • 我不这么认为,它只是将subDomainNamesubDomainSuffix 的值组合起来,对吧?这些字段已经存在于请求中,我们只是在前端将它们组合起来。除非我误会了,否则还有更多。
  • 完美,知道了@WesleySmith
  • @WesleySmith 感谢您的建议,按照您说的做了(使用隐藏字段),并且运行良好。

标签: php database laravel validation laravel-6


【解决方案1】:

尝试遵循验证规则

$this->validate($request, [
    'subDomainName' => 'required',
    'subDomainSuffix' => 'required',
    //'package_type' => 'required',
    'lang' => 'required',
    'theme' => 'required',
    'paymentoption' => 'required',
    'domain'  => [
        'required',
        Rule::unique('apps')->where(function ($query) use ($request) {
            return $query->whereDomain($request->subDomainName.'.'.$request->subDomainSuffix);
        }),
    ]
],
[
    'domain.unique' => __('messages.app.error.unique', [
        'subDomainName' => $request->subDomainName, 
        'subDomainSuffix' => $request->subDomainSuffix
    ]),
]);

【讨论】:

  • 虽然这种方法可行,但它也会导致在两个不同的地方(这里,然后在使用它的后端代码中)将值连接两次。如果一个地方更新但另一个地方没有更新,这可能会导致增加维护以保持两个地方相同或将来出现错误。出于这些原因,我建议不要使用这种方法。
【解决方案2】:

首先它总是抛出一个错误,因为你做错了 html 元素名称和 id 请写在命名转换规则中

 'package_type' => 'required', worng with name.

 'theme' => 'required',wrong with name.

它从来没有完成你想要的验证。

您的唯一域验证在这里

'domain'  => [
    'required',
    Rule::unique('apps')->where(function ($query) use ($request) {
        return $query->whereDomain($request->subDomainName.'.'.$request->subDomainSuffix);
    }),
]

这是错误..

'domain.unique' => __('messages.app.error.unique', [
    'subDomainName' => $request->subDomainName, 
    'subDomainSuffix' => $request->subDomainSuffix
]),

如果不在 cmets 中告诉我,我希望它可以工作

【讨论】:

    猜你喜欢
    • 2020-08-02
    • 2014-10-16
    • 2019-03-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多