1
0
mirror of https://github.com/flarum/core.git synced 2025-08-04 15:37:51 +02:00

fix(tags): load correct user tag state and prevent N+1 queries in stateFor (#4008)

* fix: load tag state for correct user
* fix: prevent loading state if loaded previously
* fix(PHPStan): TagState can be null
This commit is contained in:
Rafał Całka
2024-08-10 19:29:26 +02:00
committed by GitHub
parent 8415d2233e
commit b3366e4c93
2 changed files with 19 additions and 4 deletions

View File

@@ -36,7 +36,7 @@ use Illuminate\Database\Eloquent\Collection;
* @property int $last_posted_user_id * @property int $last_posted_user_id
* @property string $icon * @property string $icon
* *
* @property TagState $state * @property TagState|null $state
* @property Tag|null $parent * @property Tag|null $parent
* @property-read Collection<Tag> $children * @property-read Collection<Tag> $children
* @property-read Collection<Discussion> $discussions * @property-read Collection<Discussion> $discussions
@@ -163,9 +163,18 @@ class Tag extends AbstractModel
* @param User $user * @param User $user
* @return TagState * @return TagState
*/ */
public function stateFor(User $user) public function stateFor(User $user): TagState
{ {
$state = $this->state()->where('user_id', $user->id)->first(); // Use the loaded state if the relation is loaded, and either:
// 1. The state is null, or
// 2. The state belongs to the given user.
// This ensures that if a non-null state is loaded, it belongs to the correct user.
// If these conditions are not met, we query the database for the user's state.
if ($this->relationLoaded('state') && (! $this->state || $this->state->user_id === $user->id)) {
$state = $this->state;
} else {
$state = $this->state()->where('user_id', $user->id)->first();
}
if (! $state) { if (! $state) {
$state = new TagState; $state = new TagState;

View File

@@ -57,7 +57,13 @@ class TagRepository
$query->whereVisibleTo($actor); $query->whereVisibleTo($actor);
}; };
} else { } else {
$relationsArray[] = $relation; if ($relation === 'state') {
$relationsArray['state'] = function ($query) use ($actor) {
$query->where('user_id', $actor->id);
};
} else {
$relationsArray[] = $relation;
}
} }
} }