Laravel 复合键验证

Laravel validation for composite key

我在插入或更新之前验证一个字段,但我想要验证的是,在我的 table 中使用外键而不是主键进行验证。 我的拍卖模型是:

class Auction extends Model
{
    use HasFactory;
    protected $fillable = [
        'auction_number',
        'title',
        'description',
        'image',
        'catelogue',
        'start_date',
        'end_date',
        'start_time',
        'end_time',
        'status'
    ];
    // public function auction_category(){
    //     return $this->belongsTo(category::class,'category','id');
    // }

    public function lot(){
        return $this->hasMany(Lot::class,'auction_id','id');
    }
}

我的拍品型号是:

class Lot extends Model
{
    use HasFactory;
    protected $fillable = [
        'auction_id',
        'lot_number',
        'category',
        'description',
        'min_price',
        'max_price',
        'current_bid',
        'asking_bid',
        'thumbnail',
        'image',
        'sold',
        'closed'
    ];
    // public function seller(){
    //     return $this->belongsTo(Seller::class,'seller_id','id');
    // }
    public function auctions(){
        return $this->belongsTo(Auction::class,'auction_id','id');
    }
    public function singlecategory(){
        return $this->belongsTo(category::class,'category','id');
    }

下面是我需要这些验证的批次控制器:

public function update(Request $request, Lot $admin_lot) {
    $this->validate(
    $request, 
    [   
        'auction'=> 'required',
        'lot_number'=> 'required|unique:lots,lot_number,'.$admin_lot->auction,
        'category' => 'required',
        'description'=> 'required|min:75',
        'min_price'=> 'required|numeric|regex:/[0-9][0-9]+/u',
        'max_price'=> 'required|numeric|regex:/[0-9][0-9]+/u',
        'image.*'=> 'sometimes|nullable|file|image',
    ],
    [   
        'auction.required'    => 'Please Select Auction Number, Thank you',
        'lot_number.required'      => 'Please Select Lot Number, Thank You.',
        'description.required' => 'Please Enter Description, Thank You.',
        'description.min' => 'Please Enter Minimum of 75 Characters In Description, Thank You.',
        'min_price.required'      => 'Please Enter Min price, Thank You.',
        'min_price.numeric'      => 'Please Enter a Valid Min price Without Any Special characters, Thank You.',
        'min_price.regex'      => 'Please Enter Valid Min Price, Thank You.',
        'max_price.required'      => 'Please Enter Max price, Thank You.',
        'max_price.numeric'      => 'Please Enter a Valid Max price Without Any Special characters, Thank You.',
        'max_price.regex'      => 'Please Enter Valid Max price, Thank You.',
        'image.image'      => 'Please Select Image, Thank You.',
        ]);
//then rest of my functions
if ($request->file('image')) {
            if (File::isDirectory(public_path($admin_lot->image))) {
                File::deleteDirectory(public_path($admin_lot->image));
                File::deleteDirectory(public_path($admin_lot->thumbnail));
                $hashpath = 'public/lot/images/lot_'.uniqid().'_'.time();
                $hashpaththumb = 'public/lot/thumbnail/lot_'.uniqid().'_'.time();
                foreach($request->file('image') as $imagefile){
                    if (!empty($imagefile)) {
                        $imagepath = $hashpath.'/'.'lot_'.uniqid().'_'.time().'.jpg';
                        $thumbnailpath = $hashpaththumb.'/'.'lot_'.uniqid().'_'.time().'.jpg';
                        $image = Image::make($imagefile)->resize(265,275)->encode('jpg');
                        $thumb = Image::make($imagefile)->resize(60,45)->encode('jpg');
                        Storage::put($imagepath, (string) $image->encode());
                        Storage::put($thumbnailpath, (string) $thumb->encode());
                    }
                }   
                $imageurl = Storage::url($hashpath);
                $thumburl = Storage::url($hashpaththumb);
            }else{
                $hashpath = 'public/lot/images/lot_'.uniqid().'_'.time();
                $hashpaththumb = 'public/lot/thumbnail/lot_'.uniqid().'_'.time();
                foreach($request->file('image') as $imagefile){
                    if (!empty($imagefile)) {
                        $imagepath = $hashpath.'/'.'lot_'.uniqid().'_'.time().'.jpg';
                        $thumbnailpath = $hashpaththumb.'/'.'lot_'.uniqid().'_'.time().'.jpg';
                        $image = Image::make($imagefile)->resize(265,275)->encode('jpg');
                        $thumb = Image::make($imagefile)->resize(60,45)->encode('jpg');
                        Storage::put($imagepath, (string) $image->encode());
                        Storage::put($thumbnailpath, (string) $thumb->encode());
                    }
                }   
                $imageurl = Storage::url($hashpath);
                $thumburl = Storage::url($hashpaththumb);            
            }
        }else{

            $imageurl=$admin_lot->image;
            $thumburl =$admin_lot->thumbnail;
        }
        $admin_lot->update([
            'auction_id'=> $request->auction,
            'lot_number'=> $request->lot_number,
            'category' => $request->category,
            'description'=> $request->description,
            'min_price'=> str_replace(',', '', $request->min_price),
            'max_price'=> str_replace(',', '', $request->max_price),
            'thumbnail'=> $thumburl,
            'image'=> $imageurl
        ]);

        $notification = array(
            'message' => 'Lot updated successfully!',
            'alert-type' => 'success'
        );
        return redirect()->back()->with($notification); 
}

根据上面的代码,拍卖是我存储在地块 table 中的外键,拍卖是 table 拍卖的主键。所以我想要的是每次拍卖都有唯一的批号,例如:

auction 1 can have lot numbers 1,2,3,4, etc
auction 2 also can have 1,2,3,4,5 etc

但是从上面的例子来看,拍卖 1 不能有重复的数字 1、2、3、4,因为它们已经被分配给同一个拍卖编号 1。那么我该如何添加验证,因为我有已尝试验证主键,例如:

auction 1 from above has the 1,2,3,4 and if I assign these to auction 2 then it gives an error saying it is already taken but the auction is different,

所以它必须将它们视为有效。那么我该怎么做请有人帮我完成这件事

您可以使用Rule::unique来实现您的验证规则

$this->validate(
$request, 
[   
    'auction'=> 'required',
    'lot_number'=> ['required',
         Rule::unique('lots')->where(function($query) {
              $query->where('auction_id', '!=', $request->auction)
                    ->where('lot_number','!=',$request->lot_number);
         })            
     ],
    'category' => 'required',
    'description'=> 'required|min:75',
    'min_price'=> 'required|numeric|regex:/[0-9][0-9]+/u',
    'max_price'=> 'required|numeric|regex:/[0-9][0-9]+/u',
    'image.*'=> 'sometimes|nullable|file|image',
]
// other code

你可以使用闭包laravel custom validation using closure

$auction = $request->input('auction');
$validated = $request->validate([
    'lot_number' => ['required',function($attribute, $value, $fail) use ($auction) {
        if(Lot::where('auction_id', $auction)->where('lot_number', $value)->exists()){
            $fail('Given lot no. is already exists');
        }
        
    }],
]);