在我目前的系统中,用户可以为产品撰写评论。
以下是在我的控制器中进行验证和创建评审的方法:
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();
}
如何防止用户针对已评论过的图书或产品发布新评论?
您可以在
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');
}
首先,作为一个好习惯,尽可能将所有逻辑放在控制器中。 您的 Review 模型文件中不需要 storeReviewForBook。
我会像这样写你的帖子和验证函数,
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中放置唯一索引,在评论表中放置book_id。将 user_id 和 book_id 作为一个数组放置,以便唯一索引将是 2 列组合的索引。
//in migration file
$table->unique(['user_id','book_id']);