Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/233.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php Laravel检查唯一规则,而不将属性作为数据而不是url参数发送_Php_Laravel_Validation_Eloquent_Request - Fatal编程技术网

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'))
        ],
    ];
}