Как получить владельцев группы? (Вопрос по коду Rails)

Я думаю, что этот вопрос углубляется в детали Rails, но попробую:

Я пытаюсь разобраться, как отображать владельца или владельцев каждой группы на странице списка групп (аналогично этой странице).

Моя отправная точка — модель группы, которая, как мне кажется, подразумевает, что признак владельцев группы не привязан напрямую к группе (в отличие, скажем, от “full_name”, который, как я вижу, является частью схемы группы в конце этой ссылки).

Таким образом, очевидно, что я не могу вызвать group.owners так, как могу вызвать group.full_name. Аналогично, я не думаю, что смогу получить эту информацию через API, просто запросив данные о группе, поскольку “owners” не кажется одним из возвращаемых значений.

Как мне получить список владельцев группы, чтобы отобразить эту информацию?

Мне не совсем понятно, чего именно вы пытаетесь достичь, но, кажется, вам нужен GroupUser. Вы можете получить список идентификаторов групп и идентификаторов пользователей их владельцев с помощью чего-то вроде:

GroupUser.where(owner: true).pluck("group_id", "user_id")

Спасибо, это определённо шаг вперёд. Моя цель — отображать владельцев группы под названием группы на странице списка групп.

РЕДАКТИРОВАНИЕ: Например, что-то вроде этого:

<script type="text/x-handlebars" data-template-name="components/groups-info">
 {{#if showFullName}}
  <span class="groups-info-name">{{group.full_name}}</span>
  {{#each group.group_users as |gUser|}}
      {{#if gUser.owner}}
            <div>{{gUser.user.name}}</div>
      {{/if}}
  {{/each}}
{{else}}
  <span class="groups-info-name">{{group.displayName}}</span>
{{/if}}
</script>

Это работает не совсем так, как нужно. Чего не хватает?

Вам потребуется написать небольшой плагин для сериализации нужной информации. Я видел ваш пост в Marketplace. Надеюсь, кто-нибудь откликнется!

Если вы хотите всерьез заняться изучением плагинов, рекомендую ознакомиться со статьей: Learn how to start building stuff for Discourse if you're newbie (like myself)

Я набросал кое-что в качестве очень грубого доказательства концепции, которое может послужить отправной точкой для самостоятельного разбирательства:

my-plugin/plugin.rb

# frozen_string_literal: true

# name: Group Test
# about: Group Test
# version: 0.1
# authors: Tester
# url: https://github.com/someone/something

enabled_site_setting :group_test_enabled

after_initialize do
  add_to_serializer(:basic_group, :owners) do
    GroupUser.where(group_id: object.id, owner: true).pluck("user_id")
  end
end

my-plugin/config/settings.yml

plugins:
  group_test_enabled:
    default: false
    client: true

Во вкладке <head> вашей темы

<script type="text/x-handlebars" data-template-name="components/groups-info">
 {{#if showFullName}}
   <span class="groups-info-name">{{group.full_name}}</span>
 {{else}}
   <span class="groups-info-name">{{group.displayName}}</span>
   {{#each group.owners as |owner|}}
      {{#if owner}}
        <div>{{owner}}</div>
      {{/if}}
   {{/each}}
 {{/if}}
</script>

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

Дальше я помочь не смогу, так что удачи!

Это чрезвычайно полезно — спасибо. Понимаю, что вы не можете предоставить дополнительную помощь с кодом, но надеюсь, смогу задать два общих вопроса, которые могут быть полезны и другим:

— Можете ли вы кратко объяснить, почему здесь необходим сериализатор? (Пытаюсь понять это не только в данном случае, но и для других кастомизаций)

И ещё один быстрый вопрос: могу ли я добиться этого прямо в своей панели управления? (Создание плагина, безусловно, было бы более организованным решением, но так как я использую хостинговый тариф, я не могу напрямую импортировать новые плагины — это требует как минимум нескольких дополнительных шагов)

Конечно :slight_smile: Данные по умолчанию не доступны через BasicGroupSerializer. Мы включаем только то, что необходимо.

Проследить за этим немного запутанно, но единственная причина, по которой компонент groups-info имеет доступ к тем данным, которые у него есть, заключается в том, что он получает объект group от своего родительского шаблона:

А родительский шаблон получает его от контроллера:

Боюсь, что нет. Если только я не знаю о какой-то магии!

Отлично. Большое спасибо за эту полезную информацию.

Редакция: перемещено сюда, после того как я осознал, что заданный вопрос более уместен в отдельной теме.

Привет @tshenry, я пытаюсь запустить плагин, который включает код, похожий на тот, что вы привели выше, для раскрытия информации о владельце группы. У меня возник один вопрос, который я пытаюсь прояснить:

— Соответствующая модель здесь — «group» (на которую ссылается groups-info).
— Но в сериализаторе вы не пишете: add_to_serializer(:group, :owners)… Вместо ссылки на :group вы ссылаетесь на :basic_group, например:

add_to_serializer(:basic_group, :owners)

Почему вы ссылаетесь на basic_group, а не на group, в add_to_serializer?

Дело в том, что в данном случае ‘basic_group’ — это имя сериализатора: discourse/app/serializers/basic_group_serializer.rb at main · discourse/discourse · GitHub

Как вы определили, что именно этот сериализатор подходит для данного случая?

Вот что мне удалось выяснить: в контроллере групп, в действии index, есть функция (или метод) render_json_dump, которая включает BasicGroupSerializer в вызов serialize_data.

Соответствующая страница для отображения данных о группах — это индекс групп, поэтому именно действие index в контроллере здесь нужно рассматривать.

Именно так вы поняли, что BasicGroupSerializer — это правильный сериализатор, на который нужно ссылаться?

Если всё верно, то используется ли GroupShowSerializer для отображения страницы отдельной группы, поскольку именно этот сериализатор указан в действии show контроллера? (страница с деталями группы — хотя, похоже, представления groups.show нет).

А что в случае, если сериализатор не указан, например, в действии new контроллера?

Действительно, это и есть причина.

Потому что это не метод GET. Сериализация нужна для больших объёмов повторяющихся данных, передаваемых по нисходящему каналу.

@JQ331, обратите внимание на ядро конфигурации маршрутизатора здесь: discourse/config/routes.rb at main · discourse/discourse · GitHub

Это покажет, как все маршруты и методы контроллеров подключены в базовом приложении.

Также рекомендую ознакомиться с руководством: Rails Routing from the Outside In — Ruby on Rails Guides

Ещё один момент, который может сбить с толку и который меня самого сильно запутывал в начале: Rails — это фреймворк, и для реализации своей магии он использует очень строгие соглашения об именовании. Если вы к этому не привыкли, не сразу понятно, как всё связано между собой, но если учесть соглашения об именовании, картина начинает проясняться.

Спасибо за эту ссылку — очень полезно. Мне сам файл маршрутов кажется немного запутанным. Например, насколько я вижу, в нём нет ссылки на действие контроллера groups#index, хотя именно это действие явно отвечает за основную страницу группы. Однако я вижу действие groups#index, когда запускаю:
% rails routes, что, думаю, тоже удобный способ понять, какой странице соответствует контроллер.

Не игнорируйте документацию :wink:

Вот как это работает:
discourse/config/routes.rb at 57a8b3b964f867818c4dbfe394b762c0a286c28d · discourse/discourse · GitHub

Смотрите: Rails Routing from the Outside In — Ruby on Rails Guides

Это очень лаконичный способ маршрутизации множества методов.