复合键的 Laravel 验证
Posted
技术标签:
【中文标题】复合键的 Laravel 验证【英文标题】:Laravel validation for composite key 【发布时间】:2021-09-30 07:54:50 【问题描述】:我在插入或更新之前验证一个字段,但我想要验证的是,在我的表中使用外键而不是主键进行验证。 我的拍卖模式是:
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);
从上面的代码中,拍卖是我存储在lots 表中的外键,而拍卖是表auctions 中的主键。所以我想要的是每次拍卖都有唯一的批号,例如:
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,
所以它必须将它们视为有效。那么我该怎么做呢,请有人帮我完成这件事
【问题讨论】:
批号存储逗号分隔? 没有一个又一个喜欢:aution 1 lot 1 和第二个 aution 1 lot 2 像这样 你能显示你的控制器代码吗? 请添加控制器和型号代码 在我的问题中,拍卖是拍卖的主键,这是我的地块表中的外键。所以在我的拍品表中,我可以进行任意数量的拍卖,对吧? 【参考方案1】:您可以使用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
【讨论】:
女士,它不工作。但实际代码必须为插入功能工作,但它不工作它给我错误说批号已经被占用,但所占用的批号是另一个拍卖 您可以使用条件唯一规则。请参阅我编辑的答案。【参考方案2】:你可以使用闭包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');
],
]);
【讨论】:
您的答案对于插入效果很好,但我们如何才能进行更新?你也可以告诉我吗?即使我不更改当前批号,编辑也会出错 我已经指导您如何使用闭包进行自定义验证。现在由您决定如何根据您的要求在闭包中定义更新逻辑。 对不起,我又问了一个愚蠢的问题。我通过另一个 where 条件实现了这一点,并在闭包的使用方法中传递了当前的批次 id。非常感谢,它适用于插入和另外一个在更新函数中排除当前 id 的条件以上是关于复合键的 Laravel 验证的主要内容,如果未能解决你的问题,请参考以下文章