Like/dislike content or remove vote


I’m building an app around YouTube iframe api (which I wrote about already), where user can like/dislike content (a type of video which is a compilation of songs that can be targeted by time) or removing vote if clicking on the same vote type again. For example if user clicks on like button for the second time in a row, vote gets removed and page appears as user haven’t voted yet.

To do that I’m first deleting a record if exactly the same vote type is already associated with a user and a compilation. The result returned contains the number of how many rows were actually affected (deleted) in the process.

  • If there were rows deleted, this means user clicked same vote type again and we finish with request processing.
  • If not, we perform insert into ... on duplicate key update ... operation, because we need to record a vote if user decided to like/dislike content. Or change it if user changed his mind and instead i.e. to like the content he wants to dislike it.

In Laravel, this can be done in something like that (in controller):

public function storeVote(int $compilationId, Request $request)
{
    $vote   = $request->post('vote');
    $userId = $request->user()->id;

    $data = [
        'compilation_id' => $compilationId,
        'user_id'        => $userId,
        'vote'           => $vote
    ];

    $deletedRows = $this->compilationLike->where($data)->delete();
    
    if ($deletedRows != 0) {
        return back()->with('status', 'Vote removed');
    }

    $compilationLike = $this->compilationLike->updateOrCreate([
        'compilation_id' => $compilationId,
        'user_id'        => $request->user()->id
    ], [
        'vote'           => $vote
    ]);

    $status = $compilationLike->wasRecentlyCreated ? 'Vote saved' : 'Vote changed';

    return back()->with('status', $status);
}

Off-topic: Notice the use of wasRecentlyCreated for displaying appropriate status message. With it we can find out if record was inserted or updated.