我想使用Laravel Lighthouse GraphQL验证一个模型中的值,以便它始终与相关模型中的值匹配。
在这种情况下,Program
有一个year_id
,而Category
也有一个year_id
。我想验证Program
和Category
是否使用相同的year_id
。
GraphQL模式如下:
input CreateCategory {
year_id: ID!
name: String!
}
input CreateProgram {
year_id: ID!
name: String!
category: CreateCategoryRelation
}
input CreateCategoryRelation {
connect: ID
}
现在,如果我使用Category
创建一个year_id: 1
(返回类别ID = 1):
mutation {
createCategory(input:{
year_id: 1
name: "category in year 1"
}) {
name
id
}
}
然后尝试使用与新Program
相关的year_id: 2
创建一个Category
mutation {
createProgram(input:{
year_id: 2
name: "Program in year 2"
category: {
connect: 1
}
}) {
id
name
}
}
我希望验证,因此失败,并显示如下消息:“您不能在不同年份创建程序,因为它是类别!”
到目前为止,我还找不到一种基于其他模型中任何值进行验证的方法。 我该怎么办?
答案 0 :(得分:0)
答案 1 :(得分:0)
多亏了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;
}
}
文件App / Rules / 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)";
}
}
这为我完成了工作。