Php Laravel检查唯一规则,而不将属性作为数据而不是url参数发送
我有一个产品表和一个产品报告表。用户可以报告产品,但他只能报告一次,不能报告两次或多次 这是我的产品表:Php Laravel检查唯一规则,而不将属性作为数据而不是url参数发送,php,laravel,validation,eloquent,request,Php,Laravel,Validation,Eloquent,Request,我有一个产品表和一个产品报告表。用户可以报告产品,但他只能报告一次,不能报告两次或多次 这是我的产品表: id, heading, text, price, stock 这是我的产品报告: id, product_id, user_id, reason 我的产品过期路线: Route::post('product/{product}/report', ['as' => 'product.report', 'uses' => 'ProductController@report'])
id, heading, text, price, stock
这是我的产品报告:
id, product_id, user_id, reason
我的产品过期路线:
Route::post('product/{product}/report', ['as' => 'product.report', 'uses' => 'ProductController@report']);
现在我需要一个ProductReportRequest.php文件,它位于App\Http\Requests
中。在那里,我检查用户是否被授权,以及他是否发送了原因(值):
我现在的问题是:
正如您所看到的,路由已经包含了我希望由用户存储报告的产品(id)。因此,我不是在post请求中作为属性发送产品id,而是在url中发送,例如:product/5/report
我现在的目标是添加一条规则,用于检查具有用户id的用户(例如2
)和具有产品id的产品(例如5
)在产品报告表中是否已经存在条目。
如果是这样,请求应该以422
http代码结束,如果请求不符合规则,这是典型的http代码
但是请记住,用户id和产品id的组合必须是唯一的!因为一个用户可以报告多个产品,而在产品上可以由多个用户报告
我已经在中找到了unique
验证规则,但我认为它们只适用于请求属性,而不是url。在不将用户id和产品id作为请求属性发送的情况下,如何进行验证
PS:我使用的是Laravel6.x
亲切的问候 您可以从创建自定义规则开始: MyRules.php
classmyrules{
公共静态函数existsForClient($table,$field){
返回规则::存在($table,$field)->其中(函数($query){
$query->where('user\u id',Auth::user()->id);
});
}
}
然后像这样使用规则:
函数规则(){
返回[
“值”=>[
“必需”,
'字符串',
“最大值:65535”,
MyRules::Existsfourser('products','product_id'),
]
];
}
当然,您需要向MyRules类添加有效的命名空间。您需要一个自定义规则,如:
<?php
namespace App\Rules;
use Illuminate\Contracts\Validation\Rule;
class OneProductPerUser implements Rule
{
/**
* @var int
*/
private $userId;
/**
* @var int
*/
private $productId;
public function __construct($userId, $productId)
{
$this->userId = $userId;
$this->productId = $this->productId;
}
/**
* Determine if the validation rule passes.
*
* @param string $attribute
* @param mixed $value
* @return bool
*/
public function passes($attribute, $value)
{
//import the correct Eloquent model of the ProductReport model
$reports = ProductReport::where('user_id', $this->userId)->where('product_id', $this->productId)->count();
return $reports === 0;
}
/**
* Get the validation error message.
*
* @return string
*/
public function message()
{
return 'User has already report for this product ID ' . $this->productId;
}
}
我还没有检查,但是您可以使用
$this->user()->id
访问用户对象,但该对象不起作用。我刚试过。同一用户可以多次为一个产品添加报告。另外,如何检查两列?只需添加第二个查询?@Jan,我已将我的答案从唯一更改为存在。试试看,不。。遗憾的是,它不起作用。我仍然可以插入多个报告…即使我只想检查产品\u id
它不工作。。。我已经添加了“唯一:产品报告,产品id”
,但我仍然可以插入多个reports@Jan首先,您必须在迁移中进行约束,换句话说,在数据库表中,您必须进行约束索引,以便只能保存同一用户标识和同一产品标识中的一种。然后,您需要进行PHP验证,如果适合您的应用程序,最后还需要进行前端JS/HTML验证。此外,验证规则与保存数据无关。这意味着,如果出现一些误解,DB将不会阻止保存。为此,您需要设置正确的索引/约束。即$table->index(['user\u id','product\u id')代码>。
<?php
namespace App\Rules;
use Illuminate\Contracts\Validation\Rule;
class OneProductPerUser implements Rule
{
/**
* @var int
*/
private $userId;
/**
* @var int
*/
private $productId;
public function __construct($userId, $productId)
{
$this->userId = $userId;
$this->productId = $this->productId;
}
/**
* Determine if the validation rule passes.
*
* @param string $attribute
* @param mixed $value
* @return bool
*/
public function passes($attribute, $value)
{
//import the correct Eloquent model of the ProductReport model
$reports = ProductReport::where('user_id', $this->userId)->where('product_id', $this->productId)->count();
return $reports === 0;
}
/**
* Get the validation error message.
*
* @return string
*/
public function message()
{
return 'User has already report for this product ID ' . $this->productId;
}
}
public function rules()
{
return [
'value' => [
'required',
'string',
'max:65535',
new OneProductPerUser(Auth::user()->id, $this->route('product'))
],
];
}