just in api controller me calls this:

$user->groups()->attach(Group::MODER_ID);

but $user getting this group (MODER_ID) for forum only after TWO refreshing of forum pages. How the right way change user group in any flarum execute action?
Deleting group by

$user->groups()->detach(Group::MODER_ID);

has the same behaviour

    xtreh can you explain what you are trying to accomplish? What action should lead to a group assignment ?

      clarkwinkelmann every 'tick' checking some flag's in user additional info and if it's true then add group to user, if user already has this group and flag == false, then 'detach' group.
      every 'tick' me implement by listen the serializers CurrentUserSerializer and UserSerializer

      class CheckUserFlag
      {
      public function subscribe(Dispatcher $events)
          {
              $events->listen(Serializing::class, [$this, 'serializing']);
          }
      
      public function serializing(Serializing $event)
      {
          $actor = $event->actor;
          if ($event->isSerializer(CurrentUserSerializer::class)) {
              updateUserGroup($actor);
          } else if ($event->isSerializer(UserSerializer::class)) {
              $user = $event->model;
              $canEdit = $actor->can('edit', $user);
              if ($canEdit) {
                  updateUserGroup($user);
              }
          }
      }
      }
      =============================================================================
      in extend.php added line $events->subscribe(Listener\CheckUserFlag::class);
      =============================================================================
       public function updateUserGroup(User $user) {
                      $newGroupIds = $user->groups()->get()->all();
                      if ($user->flag && empty($newGroupIds)) {
                          $user->raise(
                              new GroupsChanged($user, $user->groups()->get()->all())
                          );
                          $user->groups()->attach(Group::MODER_ID);
                      } else if (!$user->flag && !empty($newGroupIds)) {
                          $user->raise(
                              new GroupsChanged($user, $user->groups()->get()->all())
                          );
                          $user->groups()->detach(Group::MODER_ID);
                      }
       }
          

        xtreh this sounds like an XY problem here. There are ways to make what you describe, but it might not be the more appropriate nor the easiest solution to the actual problem you're trying to solve.

        I'm assuming you have some kind of external platform from which you want to sync groups? Can you describe the feature you're trying to implement?

          clarkwinkelmann me trying to implement 'temporary stay in a group' when time is end, group should be deleted from the user. (expression 'time is expired' it's my $user->flag).

            xtreh I'd recommend one of the following methods:

            • If you are able to setup a CRON job, create a console command that performs that check and updates the group. Then either schedule the command in CRON directly or use the scheduler provided by the fof/console package.
            • Another elegant solution could be to not actually assign the group in the database, but use the PrepareUserGroups event to dynamically assign the group. Similar to the Suspend extension, but instead of checking the suspend date and removing groups, check your own date and add a group.
            • If you really must use normal requests to perform the update, a middleware would be the right solution here. Ideally with a lottery, like the session/token clear logic of Flarum that runs on some requests, but not all the time to improve performance.

              clarkwinkelmann
              my method is working, but main problem it's when

                     if ($event->isSerializer(ForumSerializer::class)) {
                          $event->actor->groups()->attach(Group::ADMIN_ID);
                          $event->actor->save();
                          $canEdit = $event->actor->can('edit', $someuser); // IS FALSE, HOW, WE SHOULD HAVE ADMIN PRIVILEGES ??
                      }
              

              relationship and permission's didn't update, but update after some refreshing forum page by any user ( don't sure about this )

                User data is stored on the frontend to prevent an excessive number of Ajax requests for each user every time. There's no way to flush the cached user object in the frontend if the signal to drop/add groups is initiated on the backend.

                I just considered a solution. You could use the websocket to force rereading the user information for the user. That would require to use either the pusher or kyrne/websocket extension, but that is how I would solve it.

                  luceos but how EditUser->EditUserHandler doing this?

                  this.props.user.save()

                  what calls this backend in frontend?

                  luceos how to right way use pusher for update users group every tick? hook view

                  xtreh why use the ForumSerializer for that ? It's a specific serializer that answers only the forum API endpoint, which is only called internally when preloading a page. Also extending a serializer is only meant for adding data to such serializer, not perform changes in the database.

                  See my suggestions above, which I think are much more appropriate to the feature you're describing.