在我目前的系统中,用户可以为产品撰写评论。
以下是在我的控制器中验证和创建审核的方法:
public function PostAndValidate($id)
{
$input = [
'comment' => Input::get('comment'),
'rating' => Input::get('rating')
];
$review = new Review;
$validator = Validator::make( $input, $review->getCreateRules());
return to product page with error message
if ($validator->passes()) {
$review->storeReviewForBook($id, $input['comment'], $input['rating']);
return Redirect::to('book/'.$id.'#reviews-anchor')->with('review_posted',true);
}
return Redirect::to('book/'.$id.'#reviews-anchor')->withErrors($validator)->withInput();
}
如何阻止用户针对已经审核过的图书或产品发布新评论?
答案 0 :(得分:2)
您可以在storeReviewForBook
方法中执行以下操作:
$book = Book::find($id);
if(in_array(Auth::user()->id, $book->reviews->lists('user_id')->all())) {
return redirect()->back()->with('message', 'You already reviewed this book');
}
答案 1 :(得分:1)
首先作为一个好习惯,尽可能将所有逻辑放在控制器中。你在评论模型文件中不需要storeReviewForBook。
我会像你这样编写你的postAndValidate函数,
public function PostAndValidate($id)
{
$input = [
'comment' => Input::get('comment'),
'rating' => Input::get('rating')
];
$review = new Review;
$validator = Validator::make( $input, $review->getCreateRules());
if ($validator->passes()) {
//queries for a review with book id and user id matching the current transaction
$existing = Review::where('book_id','=',$id)
->where('user_id','=',Auth::user()->id)
->first();
//last query returns null if nothing is returned
if($existing!=null)
{
return redirect()->back()->with('message', 'You already reviewed this book');
}
else
{
$review->comment = $input['comment'];
$review->rating = $input['rating'];
$review->book_id = $id;
$review->user_id = Auth::user()->id;
$review->save();
return Redirect::to('book/'.$id.'#reviews-anchor')->with('review_posted',true);
}
return Redirect::to('book/'.$id.'#reviews-anchor')->withErrors($validator)->withInput();
}
当您将逻辑放在控制器中时,模型应该是与数据库交互的层。它也更易读,更容易调试。
修改强> 作为数据完整性的一种形式,您可以在user_id中放置唯一索引,在review表中放置book_id。将user_id和book_id放在一个数组中,这样唯一索引就是2列的组合。
//in migration file
$table->unique(['user_id','book_id']);