0

使用 Laravel Lighthouse GraphQL,我想验证一个模型中的值,以便它始终与相关模型中的值匹配。

在这种情况下 aProgram有 ayear_id并且 aCategory也有 a year_id。我想验证 theProgramCategoryuse 相同year_id

GraphQL Schema 如下所示:

input CreateCategory {
    year_id: ID!
    name: String!
}

input CreateProgram {
    year_id: ID!
    name: String!
    category: CreateCategoryRelation
}

input CreateCategoryRelation {
    connect: ID
}

现在,如果我创建一个Categoryyear_id: 1返回类别 id=1):

mutation {
  createCategory(input:{
    year_id: 1
    name: "category in year 1"
  }) {
    name
    id
  }
}

然后尝试创建一个Programyear_id: 2新的相关的Category

mutation {
  createProgram(input:{
    year_id: 2
    name: "Program in year 2"
    category: {
      connect: 1
    }
  }) {
    id
    name
  }
}

我希望验证失败,并显示“您不能在不同年份创建程序,因为它是类别!”这样的消息。

到目前为止,我找不到基于另一个模型中的任何值进行验证的方法。我怎样才能做到这一点?

4

2 回答 2

2

感谢 Enzo Notario 的回答,我找到了解决方案。如果其他人想要更多关于你如何我相信这可以做得更漂亮)编写你自己的验证的详细信息,这里是我的代码:

type Mutation {
    createProgram(input: CreateProgram! @spread): Program! @create @yearValidation
}

文件 App/GraphQL/Directives/YearValidationDirective.php:

<?php

namespace App\GraphQL\Directives;

use App\Rules\SameYear;
use Illuminate\Support\Facades\DB;
use Nuwave\Lighthouse\Schema\Directives\ValidationDirective;

class YearValidationDirective extends ValidationDirective
{
    /**
     * List of all relations that should be checked for having the same year
     */
    private $relations = [
        'category' => true
    ];

    /**
     * Name of the directive.
     *
     * @return string
     */
    public function name(): string
    {
        return 'yearValidation';
    }

    /**
     * @return mixed[]
     */
    public function rules(): array
    {
        if (isset($this->args['year_id'])) {
            // year_id is given, get it
            $year_id = $this->args['year_id'];
        } else {
            // year_id not given, get it from the model
            $id = $this->args['id'];
            $fieldName = $this->resolveInfo->fieldName; // "updateTableName"
            $tableName = substr($fieldName, 6);
            $year_id= DB::table($tableName)->findOrFail($id)->year_id;
        }

        $relationFields = [];

        foreach($this->args as $field => $arg) {
            if (is_array($arg) && isset($this->relations[$field])) {
                $relationFields[$field] = [new SameYear($year_id)];
            }
        }

        return $relationFields;
    }
}

文件应用程序/规则/SameYear.php:

<?php

namespace App\Rules;

use Illuminate\Support\Facades\DB;
use Illuminate\Contracts\Validation\Rule;

class SameYear implements Rule
{
    protected $year_id;
    protected $found_year_id;
    protected $tableName;
    protected $connect;

    /**
     * Create a new rule instance.
     *
     * @return void
     */
    public function __construct($year_id)
    {
        $this->year_id = $year_id;
    }

    /**
     * Determine if the validation rule passes.
     *
     * @param  string  $attribute
     * @param  mixed  $value
     * @return bool
     */
    public function passes($attribute, $value)
    {
        $this->connect = $value['connect'];
        $this->tableName = ucfirst($attribute);
        $this->found_year_id = DB::table($this->tableName)->find($this->connect)->year_id;
        return intval($this->found_year_id) === intval($this->year_id);
    }

    /**
     * Get the validation error message.
     *
     * @return string
     */
    public function message()
    {
        return "Year_id's must be the same! $this->tableName (id: $this->connect) must have year_id: $this->year_id (found: $this->found_year_id)";
    }
}

这对我有用。

于 2019-12-29T22:33:39.487 回答
1

您可以使用https://lighthouse-php.com/4.7/security/validation.html#validate-fields进行自己的验证

于 2019-12-29T13:05:28.777 回答