【问题标题】:Right way to handle this situation using Laravel validation使用 Laravel 验证处理这种情况的正确方法
【发布时间】:2019-01-09 23:02:30
【问题描述】:

我是 Laravel 的新手,我想对如何处理这种情况有一些指导。

我有两个实体:广告和提名。广告可以有多个提名。

在控制器中,我收到两个外部输入:[ad_id] 和 [nomination_id] 都需要。

我对这两个输入要做的是:

  • 检查 [ad_id] 是否为现有的 Ad 实体,并且其属性“active”是否为真。

  • 检查 [nomination_id] 是现有的提名实体。

  • 仅当 [ad_id] 是现有广告且 [nomination_id] 是现有提名时,检查此提名是否属于此广告。

你能告诉我一个关于如何只使用验证类来管理这个的例子吗?

【问题讨论】:

  • 没有看到最后一行。我的答案显示在控制器中。

标签: laravel validation laravel-validation


【解决方案1】:

你可以这样写你的验证规则

public function rules()
{
    return [
        'ad_id' => [
            'bail',
            'required',
            Rule::exists('ads')->where(function ($query) use ($request) {
                $query->where([
                    ['active' => 1],
                    ['id' => $request->ad_id]
                ]);
            }),
        ],
        'nomination_id' => [
            'bail',
            'required',
            Rule::exists('nominations')->where(function ($query) use ($request) {
                $query->where([
                    ['ad_id' => $request->ad_id],
                    ['id' => $request->nomination_id]
                ]);
            }),
        ],
    ];
}

假设您有 adsnominations 是表名,主键字段是 idad_id 作为提名表中的外键。

【讨论】:

  • plusOne。也许只是 nomination_id 规则就足够了?
  • 有问题的是它提到在其他验证之前应该检查这两个字段。
  • 这种方式支持单独的消息。很好的答案。
  • 使用Rule helper 进行这种琐碎的验证是多余的 IMO。 18 行代码而不是 2 行。无论如何答案都是正确的。
  • 您在哪部分指定必须仅对 id [ad_id] 和 [nomination_id] 结果作为现有实体执行提名所有权检查?
【解决方案2】:

要验证 ad_idnomination_id,可以使用 laravel in 规则。

FormRequest 类

public function rules()
{

    return [
        'ad_id'         =>  [
                                'required',
                                Rule::in(Ad::where('active', true)->pluck('id')->toArray()),
                            ],
        'nomination_id' =>  [
                                'required',
                                Rule::in(Nomination::where('id', $this->nomination_id)->where('ad_id', $this->ad_id)->pluck('id')->toArray()),
                            ],
    ];
}

Rule::in(Ad::where('active', true)->pluck('id')->toArray()), 规则将检查ad_id 是否存在于Ad 的ID 数组中,其中active 字段为true

Rule::in(Nomination::where('id', $this->nomination_id)->where('ad_id', $this->ad_id)->pluck('id')->toArray()), 规则将检查nomination_id 是否存在于与Ad 相关的Nomination 的ID 数组中。

【讨论】:

    【解决方案3】:

    这非常简单 - 您可以编写验证规则,就像您在问题中列出的那样:

    $validator = Validator::make($request->only('ad_id', 'nomination_id'), [
        'ad_id' => 'required|exists:ads,id,active,1',
        'nomination_id' => 'required|exists:nominations,id,ad_id,' . $request->ad_id,
    ]);
    
    if ($validator->fails()) {
        ...
    }
    

    【讨论】:

    • 这是否检查 id 和 ad_id 是否属于同一行?
    • @Tpojka id 是什么意思?我们在问题中有ad_idnomination_id。我们没有提供有关包含这些外键列的行的任何信息。
    • 我的意思是验证器中的第二行。它是否检查 ad_id 是否属于找到 nomination_id 的右行,或者只是检查 nominations 表中任何行中是否存在 ad_id?
    • @Tpojka 它通过idad_id 列检查所述提名是否存在。我们没有提供有关具有这些外键列的行的任何信息。为了验证它(假设我们有这一行的id,它的表是rows)我们需要单独的规则:'id' => 'required|exists:rows,id,ad_id,' . $request->ad_id . ',nomination_id,' . $request->nomination_id。这取决于我们是否拥有该信息以及是否需要对其进行验证的情况。
    • 类似的东西。 'nomination_id' => 'required|exists:nominations,id,ad_id,' . $request->ad_id 似乎应该可以工作。
    【解决方案4】:
    $inputAd = <some_value>;
    $inputNomination = <some_value>;
    
    $nomination = Nomination::where(['id' => $inputNomination])->with(['ads'])->first();
    
    if(!$nomination || !($nomination->ad_id == $inputAd)) {
        // not the same
    }
    
    // same
    

    【讨论】:

    • 虽然此代码可能会回答问题,但提供有关此代码为何和/或如何回答问题的额外上下文可提高其长期价值。
    • @JensHabegger 正确。实际上,这不是正确的选择,因为我在检查 OP 想要验证器解决方案之前编写了它。代码最好放在控制器中。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-07-28
    • 2019-02-19
    • 2013-03-21
    • 2020-02-06
    • 2011-03-26
    • 1970-01-01
    • 2014-04-15
    相关资源
    最近更新 更多