/**
  * @throws \Exception
  * @return CommandResponse
  */
 public function execute()
 {
     $typeId = $this->_resourceType . '_id';
     $existing = Favourite::where($typeId, '=', $this->_resourceId)->whereUserId(Auth::user()->id)->first();
     $isFavourited = false;
     if ($existing) {
         $existing->delete();
     } else {
         $fav = new Favourite();
         $fav->{$typeId} = $this->_resourceId;
         $fav->user_id = Auth::user()->id;
         $fav->created_at = time();
         $fav->save();
         $isFavourited = true;
     }
     $resourceUser = ResourceUser::get(Auth::user()->id, $this->_resourceType, $this->_resourceId);
     $resourceUser->is_favourited = $isFavourited;
     $resourceUser->save();
     $resourceTable = $this->_resourceType . 's';
     // We do this to prevent a race condition. Sure I could simply increment the count columns and re-save back to the db
     // but that would require an additional SELECT and the operation would be non-atomic. If two log items are created
     // for the same resource at the same time, the cached values will still be correct with this method.
     DB::table($resourceTable)->whereId($this->_resourceId)->update(['favourite_count' => DB::raw('(
                 SELECT
                     COUNT(id)
                 FROM
                     favourites
                 WHERE ' . $typeId . ' = ' . $this->_resourceId . ')')]);
     return CommandResponse::succeed(['is_favourited' => $isFavourited]);
 }