From 46ce7fb0b6160fd29396eeac53d4c513c1862643 Mon Sep 17 00:00:00 2001 From: grafi Date: Sat, 31 Jul 2021 15:08:56 +0200 Subject: [PATCH] Refactor with exceptions --- VoiceController.php | 91 ++++++++++++++++++++++++++------------------- 1 file changed, 53 insertions(+), 38 deletions(-) diff --git a/VoiceController.php b/VoiceController.php index b0a3f1c..bf6c06b 100644 --- a/VoiceController.php +++ b/VoiceController.php @@ -1,48 +1,63 @@ +validate([ 'question_id'=>'required|int|exists:questions,id', 'value'=>'required|boolean', ]); - $question=Question::find($request->post('question_id')); - if (!$question) - return response()->json([ - 'status'=>404, - 'message'=>'not found question ..' - ]); - if ($question->user_id==auth()->id()) - return response()->json([ - 'status' => 500, - 'message' => 'The user is not allowed to vote to your question' - ]); - - //check if user voted - $voice=Voice::where([ - ['user_id','=',auth()->id()], - ['question_id','=',$request->post('question_id')] - ])->first(); - if (!is_null($voice)&&$voice->value===$request->post('value')) { - return response()->json([ - 'status' => 500, - 'message' => 'The user is not allowed to vote more than once' - ]); - }else if (!is_null($voice)&&$voice->value!==$request->post('value')){ - $voice->update([ - 'value'=>$request->post('value') - ]); - return response()->json([ - 'status'=>201, - 'message'=>'update your voice' - ]); + try { + $question = Question::findOrFail($request->post('question_id')); + + $vote = $question->vote($request->post('value')); + $responseData = $vote->wasRecentlyCreated + ? ['status' => 200, 'message' => 'Voting completed successfully'] + : ['status' => 201, 'message' => 'update your voice']; + } catch(ModelNotFoundException $e) { + // We should be able to remove this catch. Validation should assure we never get to this? + $responseData = ['status' => 401, 'message' => 'Question not found.']; + } catch (IsOwnQuestionException $e) { + $responseData = ['status' => 401, 'message' => 'The user is not allowed to vote to your question']; + } catch (UserAlreadyHasVotedException $e) { + $responseData = ['status' => 500, 'message' => 'The user is not allowed to vote more than once']; } - $question->voice()->create([ - 'user_id'=>auth()->id(), - 'value'=>$request->post('value') - ]); + return response()->json($responseData); +} - return response()->json([ - 'status'=>200, - 'message'=>'Voting completed successfully' - ]); +class User extends Model { + + public function hasAlreadyVotedForQuestion(Question $question, $value) + { + return $question + ->voice() + ->where('user_id', $this->id) + ->where('value', $value) + ->exists(); + } + + public function questionBelongsToUser(Question $question) + { + return $this->id === $question->user_id; + } + + public function questions() + { + return $this->hasMany(Question::class); + } +} + +class Question extends Model { + + public function vote($value) + { + throw_if(auth()->questionBelongsToUser($this), IsOwnQuestionException::class); + + throw_if(auth()->hasAlreadyVotedForQuestion($this, $value), UserAlreadyHasVotedException::class); + + return Voice::updateOrCreate( + ['user_id' => auth()->id], + ['value' => $value] + ); + } } \ No newline at end of file