cybercog / laravel-love

Add Social Reactions to Laravel Eloquent Models. It lets people express how they feel about the content. Fully customizable Weighted Reaction System & Reaction Type System with Like, Dislike and any other custom emotion types. Do you react?

Home Page:https://komarev.com/sources/laravel-love

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Why records in love_reactant_reaction_counters table are not creating?

coral4host opened this issue · comments

hey @antonkomarev
Am trying to use the react to function,
the new react has been stored successfully in love_reactions table, while cannot store the related records in love_reactant_reaction_counters and love_reactant_reaction_totals
so I cannot get the reaction count!

here is my code for following up:
Am using **MySQL 5.6

function reactTo($type,  $weight = 1)
    {
        $user = getAuthUser();
        if ($user){
            // get reaction type
            if (is_null($type)){
                $type = 'like';
            }
            $reactionType = ReactionType::fromName($type);
            $typeName = $reactionType->getName(); 

            if ($this->isNotRegisteredAsLoveReactant()){
                $this->registerAsLoveReactant();
            }

            if ($user->isNotRegisteredAsLoveReacter()){ // false
                $user->registerAsLoveReacter();
            }
            $reacterFacade = $user->viaLoveReacter();

            $isNotReacted = $reacterFacade->hasNotReactedTo($this);
            if ($isNotReacted){
                $reacterFacade->reactTo($this, $typeName, $weight);
            }
        }
        return false;
    }

First of all - I'm not sure you need to make these checks all the time:

if ($this->isNotRegisteredAsLoveReactant()){
    $this->registerAsLoveReactant();
}

if ($user->isNotRegisteredAsLoveReacter()){ // false
    $user->registerAsLoveReacter();
}

I'd suggest to simplify your code to make it like this:

function reactTo($type, $weight = 1)
{
    $user = getAuthUser();
    if (!$user) {
        return false;
    }

    if (is_null($type)){
        $type = 'like';
    }

    try {
        $user->viaLoveReacter()->reactTo($this, $type, $weight);
    } catch (\Cog\Contracts\Love\Reaction\Exceptions\ReactionAlreadyExists $exception) {
        return false;
    }
}

Second, if your service using queues - counters and totals will be created using them. You need to use sync queue driver or run php artisan queue:work while testing your app locally.

hey @antonkomarev

Firstly, really appreciate your fast reply

I've tried your suggestions, the issue hasn't solved, unfortunately.

But to be more clear my code is working well on MySQL 5.7, the problem only with MySQL 5.6
so any suggestion? or changes in the package codes to get it to work with 5.6?

That seems really strange. Could you check for mysql error logs?
I don't know any difference between these versions which could be the reason of this.

I've checked MySQL error log and laravel error log, no error related to the issue,
maybe not related to the MySQL version! but still not work.
any other suggestions?
records on love_reactions stored successfully
will there is no records in ### love_reactant_reaction_counters and love_reactant_reaction_totals

What version of Laravel Love are you using?

laravel love 8.3.1
laravel framework 5.7.29
php version 7.1.33

Creation of counter should be done after this event is dispatched:
Cog\Laravel\Love\Reaction\Events\ReactionHasBeenAdded

Then event being handled by this listener:
Cog\Laravel\Love\Reactant\Listeners\IncrementAggregates

It dispatches the async job:
Cog\Laravel\Love\Reactant\Jobs\IncrementReactionAggregatesJob::handle

Finally concrete model creation is happening in method of service class:
Cog\Laravel\Love\Reactant\ReactionCounter\Services\ReactionCounterService::findOrCreateCounterOfType

private function findOrCreateCounterOfType(
    ReactionTypeContract $reactionType
): ReactionCounterContract {
    $counter = $this->findCounterOfType($reactionType);
    if ($counter instanceof NullReactionCounter) {
        $this->reactant->createReactionCounterOfType($reactionType);
        $counter = $this->findCounterOfType($reactionType);
    }

    return $counter;
}

You could try to add some dump('something') in vendor directory and try to understand what is happening and why counter model is not creating.

@antonkomarev was debugging the code for a while by log::info , and
I found that the application is not dispatching class ReactionHasBeenRemoved,
OR getReaction() seems not working and not showing any logs from there. could you give me some steps back to keep checking?

note:
In class Reacter
functions reactTo() and createReaction() are working well. so what is happining after that?

Sorry, I was too tired when wrote that comment. On reaction create ReactionHasBeenAdded is dispatched, not ReactionHasBeenRemoved, but anyway, both of this events should check for counter existence. I've fixed text in comment.

You are calling reactTo, it checks if reaction already exists, if not - it executes createReaction method which just a wrapper for Reaction Eloquent model creation:

$this->reactions()->create([
    'reaction_type_id' => $reactionType->getId(),
    'reactant_id' => $reactant->getId(),
    'rate' => $rate,
]);

Reaction model is observed by the Cog\Laravel\Love\Reaction\Observers\ReactionObserver class, so right after model creation it just dispatches ReactionHasBeenAdded event. And counters are waiting for this event to be updated.

You could try to add debugging in \Cog\Laravel\Love\Reaction\Observers\ReactionObserver::created method. If it's not executing - it will mean only one thing - that ReactionObserver not observing Reaction model events.

Observers are registering in Cog\Laravel\Love\LoveServiceProvider::registerObservers method. If this not happening - the only one thing is in my mind: package discovery disabled in your application. Find for these lines in composer.json file:

"extra": {
    "laravel": {
        "dont-discover": [
            "*"
        ]
    }
},

If there is a reason to keep them disabled - you may register Laravel Love service providers manually in config/app.php file. There is providers array in this config file, add 2 providers right before the Application Service Providers comment:

/*
 * Package Service Providers...
 */
Cog\Laravel\Love\LoveServiceProvider::class,
Cog\Laravel\Love\LoveEventServiceProvider::class,

/*
 * Application Service Providers...
 */

Hollaaa, solved after registering the Laravel Love service providers manually in config/app.php.
really appreciate your help and reply <3.

Glad you found solution.