그룹 소유자를 조회하는 방법? (Rails 코드 질문)

이 질문은 Rails의 세부적인 부분에 해당한다고 생각하지만, 한번 살펴보겠습니다.

그룹 인덱스 페이지(이 페이지와 유사한)에서 각 그룹의 소유자(하나 또는 여러 명)를 어떻게 표시하는지 파악하려고 합니다.

출발점은 그룹 모델이며, 여기서 그룹 소유자 속성은 그룹에 직접 연결되어 있지 않음을 알 수 있습니다(예를 들어, 그 링크 하단의 그룹 스키마에 포함된 "full_name"과는 달리).

따라서 group.full_name을 호출할 수 있는 것처럼 group.owners를 호출할 수 없다는 것은 명확합니다. 마찬가지로, 그룹 정보를 가져오는 API 호출로 이 정보를 얻을 수 없다고 생각합니다. "owners"가 반환 값 중 하나가 아니기 때문입니다.

그룹의 소유자를 가져와 해당 정보를 표시하려면 어떻게 해야 할까요?

정확히 어떤 것을 달성하려는 건지 명확하지는 않지만, GroupUser를 찾고 계신 것 같습니다. 다음과 같은 코드를 사용하여 그룹 ID 목록과 해당 소유자의 사용자 ID를 가져올 수 있습니다:

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) 링크를 참고해 보시는 것을 추천합니다.

혼자서 해결할 수 있는 출발점이 될 수 있을 정도로 매우 거친 개념 증명(PoC)을 만들어 보았습니다:

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>

위 내용을 모두 조합하여 사이트 설정에서 플러그인을 활성화하면, 그룹 페이지에 그룹 소유자의 사용자 ID가 나열되어 있는 것을 볼 수 있을 것입니다.

이 이상의 도움은 드리기 어려우니, 행운을 빕니다!

정말 큰 도움이 되었습니다. 감사합니다. 추가적인 코드 도움을 드릴 수 없다는 점은 이해하고 있지만, 다른 분들도 유용하게 참고할 수 있을 것 같은 일반적인 질문 두 가지만 드려도 될까요?

– 여기서 직렬화기(serializer)가 필요한 이유를 간단히 설명해 주실 수 있을까요? (이번 경우뿐 아니라 다른 커스터마이징에서도 이해하고 싶습니다)

그리고 간단히 하나만 더 여쭤볼게요. 대시보드만으로 이걸 구현할 수 있을까요? (확실히 플러그인을 만드는 것이 훨씬 체계적이겠지만, 호스팅 플랜을 사용 중이라 새 플러그인을 직접 가져올 수 없거든요. 최소한 몇 가지 단계를 더 거쳐야 합니다)

물론이죠 :slight_smile: 기본적으로 BasicGroupSerializer에서는 해당 데이터가 노출되지 않습니다. 필요한 것만 포함시키도록 합니다.

따라가기 다소 복잡한 부분이 있지만, groups-info 컴포넌트에 특정 데이터가 이용 가능한 이유는 부모 템플릿에서 group을 전달하기 때문입니다:

그리고 부모 템플릿은 컨트롤러에서 해당 데이터를 가져옵니다:

아쉽게도 불가능합니다. 제가 알지 못하는 어떤 마법 같은 방법이 있는 한은요!

최고네요. 유용한 정보를 주셔서 정말 감사합니다.

수정: 제가 질문한 내용이 별도의 주제에 더 적합하다는 것을 깨닫고 여기로 옮겼습니다.

Hi @tshenry, 위쪽에 제공해주신 그룹 소유자 노출 관련 코드를 포함하여 플러그인을 개발하고 있습니다. 하나 고민 중인 질문이 있습니다:

– 여기서 관련 모델은 "group"입니다 (groups-info에서 참조됨).
– 하지만 직렬화기(serializer)에서 add_to_serializer(:group, :owners)라고 하지 않습니다. :group을 참조하는 대신 :basic_group을 참조하는데, 예를 들면 다음과 같습니다:

add_to_serializer(:basic_group, :owners)

add_to_serializer에서 group 대신 basic_group을 참조하는 이유는 무엇인가요?

이 경우 'basic_group’이 시리얼라이저의 이름이기 때문입니다: discourse/app/serializers/basic_group_serializer.rb at main · discourse/discourse · GitHub

이 경우 해당 직렬화기가 적합한지 어떻게 파악하셨나요?

제가 파악한 내용은 다음과 같습니다. groups 컨트롤러의 index 액션에는 render_json_dump 함수(또는 메서드)가 있으며, 이 함수의 serialize_data 호출에 BasicGroupSerializer가 포함되어 있습니다.

그룹 데이터를 표시하는 관련 페이지는 groups index이므로, 여기서 확인해야 할 것은 컨트롤러의 index 액션입니다.

BasicGroupSerializer가 여기에서 참조해야 할 올바른 직렬화기라는 것을 그렇게 아신 건가요?

만약 위 내용이 모두 정확하다면, 그룹 표시 페이지를 표시할 때는 컨트롤러의 show 액션에서 참조되는 직렬화기인 GroupShowSerializer가 사용될까요? (그룹의 세부 정보를 보여주는 페이지이지만, “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 컨트롤러 액션이 명시적으로 참조되지 않는 것으로 보이는데, 분명히 메인 그룹 페이지에 해당하는 액션임에도 불구하고 그렇습니다. 다만, % rails routes 명령을 실행하면 groups#index 액션을 확인할 수 있습니다. 이 명령은 특정 페이지가 어떤 컨트롤러에 대응하는지 파악하는 데에도 도움이 되는 방법인 것 같습니다.

문서 읽기를 건너뛰지 마세요 :wink:

이렇게 작동합니다:
discourse/config/routes.rb at 57a8b3b964f867818c4dbfe394b762c0a286c28d · discourse/discourse · GitHub

참고: Rails Routing from the Outside In — Ruby on Rails Guides

여러 메서드를 라우팅하는 매우 간결한 방법입니다.