# Устаревание использования user.groups в модели User в JavaScript

**URL:** https://meta.discourse.org/t/deprecating-the-user-of-user-groups-in-the-user-model-in-javascript/411124
**Category:** Development
**Tags:** dev-news
**Created:** [28.Август.2026 04:03:59 UTC](https://meta.discourse.org/t/deprecating-the-user-of-user-groups-in-the-user-model-in-javascript/411124 "2026-08-28T04:03:59Z")
**Posts on this page:** 6
**Page:** 1

<div class="post-metadata">

### Author: ![martin](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/martin/32/491371_2.png) [@martin](https://meta.discourse.org/u/martin)
#### Post date: [28.Август.2026 04:03:59 UTC](https://meta.discourse.org/t/deprecating-the-user-of-user-groups-in-the-user-model-in-javascript/411124/1 "2026-08-28T04:03:59Z")

</div>

Это связано как с [The road to stable, then permanent, for granular\_anonymous\_and\_logged\_in\_groups\_permissions](https://meta.discourse.org/t/the-road-to-stable-then-permanent-for-granular-anonymous-and-logged-in-groups-permissions/410178), так и с [Granular group-based permissions for anonymous and logged in users](https://meta.discourse.org/t/granular-group-based-permissions-for-anonymous-and-logged-in-users/402273)

В ядре, а также во многих темах и плагинах, стала довольно распространена такая схема:

```javascript
const groupIds = this.currentUser.groups.map((g) => g.id);
const allowedGroupIds = this.siteSettings.some_group_setting.split("|").map((groupId) => parseInt(groupId, 10));

const hasPermission = allowedGroups.some((groupId) =>
  userGroupIds.includes(groupId)
);

if (!hasPermission) {
  return;
}

```

Однако это неэффективный способ проверки прав пользователя. **Пользователь может быть участником групп, которые ему не видны** , поэтому они не сериализуются на клиенте и, следовательно, не могут использоваться последовательно и точно для проверок безопасности.

Чтобы сделать это более очевидным, мы переименовываем `currentUser.groups/user.groups` в `currentUser.visibleGroups/user.visibleGroups` в модели `User` и объявляем старое свойство устаревшим. Первый PR для реализации этого изменения — [DEV: Deprecate calling user.groups on client directly - Pull Request #42711 - discourse/discourse - GitHub](https://github.com/discourse/discourse/pull/42711) .

Если вам нужно проверять права пользователя на основе списка идентификаторов групп на клиенте в JavaScript, существует несколько альтернатив:

### Для плагинов

Расширьте сериализатор `current_user` новым атрибутом и проверяйте права пользователя с помощью `scope.in_any_groups?` на стороне сервера, что также покрывает псевдогруппы, такие как `logged_in_users` и `anonymous_users`:

```ruby
add_to_serializer(
  :current_user,
  :has_some_permission,
  include_condition: -> do
    SiteSetting.plugin_enabled
  end,
) { scope.in_any_groups?(SiteSetting.group_list_setting_map) }

```

Затем на клиенте вы можете использовать `this.currentUser.has_some_permission`.

### Для тем и компонентов

Для настроек темы типа `list` с `list_type: group` вы можете использовать `resolve_group_membership: true`:

```yaml
copy_button_allowed_groups:
  default: "1|3"
  type: list
  list_type: group
  resolve_group_membership: true

```

Это заменит `settings.copy_button_allowed_groups` на клиенте на `settings.user_in_copy_button_allowed_groups` (с префиксом `user_in_`), что является булевым значением, вычисляемым на стороне сервера на основе членства пользователя в группах.

Это также работает для объектных настроек с `type: groups`. Добавьте `resolve_group_membership: true` к свойству `groups`:

```yaml
menu_sections:
  type: objects
  default:
    - name: section 1
      groups:
        - 1
        - 3
  schema:
    name: menu section
    properties:
      name:
        type: string
      groups:
        type: groups
        resolve_group_membership: true

```

Тогда доступ будет выглядеть так:

```gjs
for (const section of settings.menu_sections) {
  if (section.user_in_groups) {
    // Пользователь входит хотя бы в одну выбранную группу для этого раздела.
  }
}

```

---

<div class="post-metadata">

### Author: ![putty](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/putty/32/370902_2.png) [@putty](https://meta.discourse.org/u/putty)
#### Post date: [28.Август.2026 13:44:56 UTC](https://meta.discourse.org/t/deprecating-the-user-of-user-groups-in-the-user-model-in-javascript/411124/2 "2026-08-28T13:44:56Z")

</div>

Привет, Мартин!  
Эти изменения вступят в силу при слиянии PR или с обновлением после слияния?

---

<div class="post-metadata">

### Author: ![Moin](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/moin/32/554653_2.png) [@Moin](https://meta.discourse.org/u/Moin)
#### Post date: [28.Август.2026 14:54:18 UTC](https://meta.discourse.org/t/deprecating-the-user-of-user-groups-in-the-user-model-in-javascript/411124/3 "2026-08-28T14:54:18Z")

</div>

Почему это важно? Это не сломает ничего. Просто в консоли браузера появится предупреждение, которое сообщит разработчикам, что им нужно внести изменения в код.

---

<div class="post-metadata">

### Author: ![putty](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/putty/32/370902_2.png) [@putty](https://meta.discourse.org/u/putty)
#### Post date: [28.Август.2026 14:59:21 UTC](https://meta.discourse.org/t/deprecating-the-user-of-user-groups-in-the-user-model-in-javascript/411124/4 "2026-08-28T14:59:21Z")

</div>

У меня есть компоненты темы, которые, как я знаю, зависят от этого, и я хотел(а) получить разъяснения. Если это просто предупреждение, но всё ещё будет работать какое-то время, я буду менее обеспокоен(а).

---

<div class="post-metadata">

### Author: ![Moin](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/moin/32/554653_2.png) [@Moin](https://meta.discourse.org/u/Moin)
#### Post date: [28.Август.2026 15:25:06 UTC](https://meta.discourse.org/t/deprecating-the-user-of-user-groups-in-the-user-model-in-javascript/411124/5 "2026-08-28T15:25:06Z")

</div>

Как правило, устаревший код продолжает поддерживаться до выхода следующей версии с расширенной поддержкой. В противном случае у форумов, использующих этот код, не было бы возможности увидеть предупреждение до того, как всё сломается.

---

<div class="post-metadata">

### Author: ![martin](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/martin/32/491371_2.png) [@martin](https://meta.discourse.org/u/martin)
#### Post date: [31.Август.2026 01:12:56 UTC](https://meta.discourse.org/t/deprecating-the-user-of-user-groups-in-the-user-model-in-javascript/411124/6 "2026-08-31T01:12:56Z")

</div>

PR уже объединён, так что это устаревший метод:

> <https://github.com/discourse/discourse/pull/42711>
>
> Renaming this array to user.visibleGroups/currentUser.visibleGroups to
> make it …clear that this is not the full list of groups a user belongs
> to, but only the ones that are visible to the current user.
> 
> Adds a \`deprecated\` warning when calling \`user.groups\` on the client, and
> adds a \`user.visibleGroups\` alias to the new property.

Но да, как говорит Moin, пока вы будете получать только предупреждения об устаревании в консоли браузера 🙂 Когда мы впервые вводим устаревание, мы вынуждены исправить все случаи использования в ядре, официальных плагинах и темах. Затем мы оставляем устаревание активным на некоторое время, чтобы постепенно исправить код в сторонних темах или позволить другим это сделать, включая клиентские темы.

Это не приведёт к постоянному удалению `user.groups` ещё долгое время, пока мы не будем уверены, что нашли все места вызова. И даже тогда мы сначала начнём показывать предупреждения в админ-панели для сайтов, в которых всё ещё используется код, обращающийся к старому методу.
