防止用户对产品提交多个评论
Prevent user from submitting more than one review for a product
在我当前的系统中,用户可以为产品撰写评论。
以下是在我的控制器中验证和创建评论的方法:
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();
}
如何防止用户post对他或她已经评论过的图书或产品进行新评论?
您可以在 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');
}
首先作为一个好习惯,尽可能将所有逻辑放在控制器中。您的评论模型文件中不需要 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 中放置一个唯一索引,在评论 table 中放置 book_id。将 user_id 和 book_id 作为数组放置,因此唯一索引将是 2 列的组合。
//in migration file
$table->unique(['user_id','book_id']);
在我当前的系统中,用户可以为产品撰写评论。
以下是在我的控制器中验证和创建评论的方法:
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();
}
如何防止用户post对他或她已经评论过的图书或产品进行新评论?
您可以在 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');
}
首先作为一个好习惯,尽可能将所有逻辑放在控制器中。您的评论模型文件中不需要 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 中放置一个唯一索引,在评论 table 中放置 book_id。将 user_id 和 book_id 作为数组放置,因此唯一索引将是 2 列的组合。
//in migration file
$table->unique(['user_id','book_id']);