Meilleure pratique pour automatiser les titres par combinaisons de groupes et de niveaux de confiance

Salut,

Je cherche la meilleure façon d’attribuer automatiquement des titres d’utilisateur en fonction d’une combinaison d’appartenance à un groupe et de niveau de confiance. Par exemple :

  • Si un utilisateur est dans le groupe A et a le niveau de confiance 1, son titre devrait être « A TL1 »
  • Si un utilisateur est dans le groupe A et a le niveau de confiance 2, son titre devrait être « A TL2 »
  • Si un utilisateur est dans le groupe B et a le niveau de confiance 1, son titre devrait être « B TL1 »
  • … et ainsi de suite

D’après ce que j’ai trouvé jusqu’à présent, la méthode principale est :

  1. Créer un groupe distinct pour chaque combinaison groupe + niveau de confiance (par exemple, a-tl1, a-tl2, b-tl1, etc.) à l’aide du plugin Dynamic Groups,
  2. Définir un titre par défaut pour chacun de ces groupes.

Bien que cela semble fonctionner, cela nécessite de créer et de maintenir un grand nombre de groupes s’il existe de nombreuses combinaisons.

Mes questions :

  • Cette configuration (de nombreux groupes dynamiques avec chacun son propre titre par défaut) est-elle la meilleure ou la seule façon de maintenir les titres synchronisés automatiquement ?
  • Existe-t-il une autre approche (utilisant le cœur de Discourse, les automatisations ou un autre plugin) pour attribuer dynamiquement des titres en fonction de conditions telles que le groupe + le niveau de confiance, sans avoir à gérer autant de groupes supplémentaires ?

Tout conseil ou partage d’expérience serait grandement apprécié. Merci d’avance !

Est-ce que cela fonctionnerait pour vous de configurer le titre en fonction de l’appartenance au groupe (A ou B) et d’avoir un composant qui ajoute le titre en fonction du niveau de confiance derrière cela ?

Je pense que vous n’auriez alors pas besoin de tous ces sous-groupes combinés :thinking:

Autre idée : Peut-être que le plugin qui définit automatiquement le niveau de confiance comme titre pourrait être utilisé comme base pour une mise à jour de titre plus complexe basée sur le niveau de confiance et l’appartenance au groupe.

3 « J'aime »

Merci pour vos suggestions

Malheureusement, je n’ai aucune expérience en programmation, je ne suis donc pas en mesure de développer ou de modifier des plugins. J’ai déjà contacté l’auteur du plugin pour lui demander si cette fonctionnalité (combiner l’appartenance à un groupe et le niveau de confiance pour les titres) pouvait être ajoutée, ou s’il avait des conseils.

Si ce sont les groupes principaux de l’utilisateur, je pense que, comme vous l’avez mentionné dans l’autre sujet, cela rendrait les choses beaucoup plus faciles.

Ensuite, vous pouvez obtenir leur groupe principal via user.primary_group puis définir le titre en utilisant user.title.

@joo J’ai ajouté le paramètre add_primary_group_title (désactivé par défaut) qui :

  • ajoute le groupe principal de l’utilisateur comme titre
  • texte derrière le titre, par exemple :

          peut être modifié à l’aide des paramètres comme auparavant.

Utilisé une touche de magie ask.discourse.com.

P.S. Si vous vous demandez comment j’ai mis en retrait le mot « peut », j’ai utilisé  . Désolé les gars.

1 « J'aime »

Salut ! Merci pour votre mise à jour et votre soutien !

Je n’ai peut-être pas bien expliqué mon besoin auparavant, alors je souhaite le clarifier à nouveau avec un exemple facile à comprendre :

Supposons que notre forum ait deux groupes principaux :

  • Groupe A : Designers
  • Groupe B : Développeurs

Pour chaque groupe, je souhaite que les utilisateurs avec différents niveaux de confiance obtiennent un titre complètement différent, comme ceci :

Pour le groupe Designers :
Niveau de confiance 1 → « Junior Designer »
Niveau de confiance 2 → « Designer »
Niveau de confiance 3 → « Senior Designer »
Niveau de confiance 4 → « Chief Designer »

Pour le groupe Développeurs :
Niveau de confiance 1 → « Junior Developer »
Niveau de confiance 2 → « Developer »
Niveau de confiance 3 → « Senior Developer »
Niveau de confiance 4 → « Tech Lead »

Ainsi, si quelqu’un est dans le groupe « Designers » avec le niveau de confiance 3, son titre devrait être « Senior Designer ».
S’il est dans le groupe « Developers » avec le niveau de confiance 2, le titre devrait être « Developer ».

J’aimerais pouvoir définir ces règles pour chaque groupe et niveau de confiance, et que les titres soient attribués automatiquement lorsque les groupes ou les niveaux de confiance des utilisateurs changent.

Auriez-vous des conseils à partager sur la façon d’y parvenir, ou envisageriez-vous d’ajouter cela comme nouvelle fonctionnalité à votre plugin ?

Merci beaucoup !

1 « J'aime »

De plus, j’essaie de réaliser cela sur mon site de test : http://ask.discourse.com/.
Je n’ai pas d’expérience en programmation, donc je ne suis pas sûr qu’il soit possible de l’implémenter moi-même.

Je pourrais utiliser une valeur de substitution, par exemple {group_nane} dans la zone de texte afin qu’il soit plus facile de modifier le titre. Je vais regarder.

Vous voudrez peut-être consulter :

Salut !

J’ai modifié le plugin pour qu’il corresponde à mes besoins, et j’aimerais partager ce que j’ai fait, mon flux de travail actuel, et quelques questions/demandes de conseils.


1. Mes Modifications

Chemin et contenu du fichier :

Fichier : app/jobs/scheduled/update-all-titles.rb

# frozen_string_literal: true

module AddTitleBasedOnTrustLevel
  class UpdateTitles < ::Jobs::Scheduled
    every SiteSetting.update_title_frequency.hours

    def execute(args)
      group_titles = JSON.parse(SiteSetting.group_trust_level_titles || "{}")

      User.find_each do |user|
        # Ignorer les administrateurs et les modérateurs, ne pas mettre à jour leurs titres
        next if user.admin? || user.moderator?

        group_id = user.primary_group_id
        next unless group_id

        group = Group.find_by(id: group_id)
        next unless group

        group_key = group.name.downcase
        tl = user.trust_level

        titles = group_titles[group_key]
        next unless titles.is_a?(Array)
        next unless tl >= 1 && tl <= 4

        new_title = titles[tl]
        next unless new_title.present?

        user.update_column(:title, new_title) if user.title != new_title
      end
    end
  end
end

Fichier : config/settings.yml

plugins:
  add_title_based_on_trust_level_enabled:
    default: false
    client: true
  group_trust_level_titles:
    default: '{"designers": ["", "Junior Designer", "Designer", "Senior Designer", "Chief Designer"], "developers": ["", "Junior Developer", "Developer", "Senior Developer", "Tech Lead"]}'
    type: string
    client: true
    multiline: true
  update_title_frequency:
    default: 24
    type: integer

2. Comment j’ai testé

J’exécute actuellement cette logique manuellement via la console Rails pour vérifier si la fonction fonctionne. Elle met bien à jour les titres des utilisateurs en masse selon mes exigences.


3. Problème d’entrée des paramètres du plugin

Il n’y a pas de bouton « Paramètres » pour ce plugin sur la page /admin/plugins. Actuellement, pour modifier la configuration, je dois visiter directement /admin/plugins/add-title-based-on-trust-level/settings.
Existe-t-il un moyen de faire apparaître le bouton ou le lien des paramètres sur la page des Plugins pour un accès plus facile ?


4. Mes paramètres actuels

Voici ma configuration JSON actuelle (je joindrai une capture d’écran également) :

{
  "designers": ["", "Junior Designer", "Designer", "Senior Designer", "Chief Designer"],
  "developers": ["", "Junior Developer", "Developer", "Senior Developer", "Tech Lead"]
}


5. Questions / Améliorations possibles

  • Cette approche (parcourir tous les utilisateurs et mettre à jour leur titre) risque-t-elle de poser des problèmes de performance s’il y a beaucoup d’utilisateurs ? Existe-t-il une meilleure pratique pour cela ?
  • Des conseils d’optimisation, que ce soit pour le travail planifié ou pour l’interface utilisateur des paramètres d’administration ?
  • Y a-t-il quelque chose d’insécurisé ou de problématique dans ma méthode dont je devrais me méfier ?

Merci beaucoup pour votre excellent travail et ce plugin utile !
Si vous avez des suggestions, ou si vous prévoyez d’améliorer la configuration des titres par groupe + niveau de confiance à l’avenir, j’aimerais beaucoup connaître vos réflexions.

2 « J'aime »

@joo Très bonne idée !

Si vous regardez le plugin maintenant, je pense que j’ai aussi fait ça (je faisais quelques tests finaux). Je vois que vous avez parcouru chaque utilisateur, mais dans les grands forums, cela peut prendre du temps.

J’ai donc fait une mise à jour SQL :

(J’ai adapté la requête d’Ask Discourse et je l’ai modifiée)

De cette façon, dans le paramètre tl1_title_on_promotion, vous devriez pouvoir utiliser quelque chose comme Junior {group_name}, de sorte que le titre deviendrait Junior Developer.

Notez que vous devrez également cocher add_primary_group_title pour que cela fonctionne.

1 « J'aime »

Merci pour l’explication, je comprends maintenant comment fonctionne votre modèle {group_name}.

Mais c’est exactement ce que je voulais dire par la différence de logique. Mon exigence principale est de pouvoir appliquer des structures de titre complètement différentes pour le même niveau de confiance, en fonction de groupes d’utilisateurs différents.

Par exemple, pour le niveau de confiance 3 :

  • Le titre pour le groupe « Designers » devrait être « Senior Designer ».
  • Le titre pour le groupe « Developers » devrait être « Tech Lead ».

Ces deux titres ont des structures complètement différentes.

J’ai essayé d’implémenter cette fonctionnalité avec une IA, mais je n’ai pas réussi. Je me demandais s’il serait possible pour vous de modifier le plugin pour prendre en charge cette logique plus granulaire ?

Ah, je crois que je vous ai mal compris alors.

Alors, est-ce que votre code ci-dessus a fonctionné ?

Non, le code précédent que j’ai essayé avec une IA n’a pas fonctionné non plus. Après avoir tout configuré, rien ne s’est passé.

Je voulais vous montrer le code complet de ma dernière tentative. J’espérais que vous pourriez voir ce que je fais de mal.

1. plugin.rb

# name: add-title-by-group-trust-level
# about: attribuer des titres via le groupe principal + niveau de confiance en utilisant SQL
# version: 0.2
# authors: your-name

# Note : Je ne suis pas sûr d'avoir besoin d'une ligne 'require' ici pour charger le fichier de tâche.
# Je soupçonne que c'est peut-être la pièce manquante.
enabled_site_setting :add_title_by_group_trust_enabled

2. app/jobs/scheduled/update-all-titles.rb

module ::Jobs
  class UpdateTitles < ::Jobs::Scheduled
    every SiteSetting.update_title_frequency.hours

    def execute(args)
      return unless SiteSetting.add_title_by_group_trust_enabled

      mappings = JSON.parse(SiteSetting.group_trust_level_titles || '{}')

      User.transaction do
        mappings.each do |group_key, titles|
          next unless titles.is_a?(Array)

          (1...titles.size).each do |tl|
            title = titles[tl]
            next if title.blank?

            group = Group.find_by("LOWER(name) = ?", group_key.downcase)
            next unless group

            User.where(primary_group_id: group.id, trust_level: tl, admin: false, moderator: false)
                .where.not(title: title)
                .update_all(title: title)
          end
        end
      end
    end
  end
end

3. config/settings.yml

plugins:
  add_title_by_group_trust_enabled:
    default: false
    client: true
  group_trust_level_titles:
    default: '{"designers":["", "Junior Designer", "Designer", "Senior Designer", "Chief Designer"],"developers":["", "Junior Developer", "Developer", "Senior Developer", "Tech Lead"]}'
    type: string
    client: true
    multiline: true
  update_title_frequency:
    default: 24
    type: integer

Voici comment je l’ai configuré dans les paramètres du site :

J’ai collé ce JSON dans le paramètre group_trust_level_titles :

{
  "designers": ["", "Junior Designer", "Designer", "Senior Designer", "Chief Designer"],
  "developers": ["", "Junior Developer", "Developer", "Senior Developer", "Tech Lead"]
}

Le problème :

La tâche UpdateTitles n’apparaît pas dans le planificateur Sidekiq (/sidekiq/scheduler).

Cependant, je l’ai testée dans la console Rails selon la méthode que l’IA m’a donnée, et la logique principale est parfaitement correcte, affichant correctement tous les utilisateurs qui remplissent les conditions.

Voici le script de test que j’ai utilisé dans la console Rails :

mappings = JSON.parse(SiteSetting.group_trust_level_titles || '{}')

mappings.each do |group_key, titles|
  next unless titles.is_a?(Array)

  (1...titles.size).each do |tl|
    title = titles[tl]
    next if title.blank?

    group = Group.find_by("LOWER(name) = ?", group_key.downcase)
    unless group
      puts "Impossible de trouver le groupe : #{group_key}"
      next
    end

    users = User.where(primary_group_id: group.id, trust_level: tl, admin: false, moderator: false)
                .where.not(title: title)
    next if users.empty?

    puts "====== Groupe : #{group.name} Niveau de confiance : #{tl} Nouveau titre : '#{title}' ======"
    users.each do |user|
      puts "Utilisateur id:#{user.id}, nom d'utilisateur:#{user.username}, titre actuel:'#{user.title}'"
    end
  end
end

Il semble donc que la logique elle-même soit correcte, mais Discourse n’enregistre pas la tâche planifiée. Quoi qu’il en soit, plus j’essaie de la modifier, plus cela devient confus… Je ne suis pas sûr que ce soit la bonne approche, et comme je ne sais pas coder, cela semble très difficile à mettre en œuvre. Avez-vous une meilleure méthode ?

Hmm… peut-être que vous voulez utiliser les paramètres d’objet :

Avec des champs comme le niveau de confiance, le groupe, le titre.

1 « J'aime »

Je voulais juste donner une mise à jour et remercier tous ceux qui ont aidé.

Avec les derniers changements, le plugin fonctionne maintenant exactement comme je le voulais ! Il attribue correctement différents titres en fonction du groupe principal et du niveau de confiance de l’utilisateur.

Je publie ci-dessous le code final fonctionnel. Il semble correct, mais comme je ne suis pas développeur, je me demandais s’il y avait des domaines d’amélioration ou d’optimisation que j’aurais pu manquer.

app/jobs/scheduled/update-all-titles.rb

# frozen_string_literal: true

module ::Jobs
  class AssignGroupBasedTitles < ::Jobs::Scheduled
    every SiteSetting.update_title_frequency.hours

    def execute(args)
      return unless SiteSetting.add_title_by_group_trust_enabled

      # 获取设置值,它现在是一个JSON字符串
      rules_json_string = SiteSetting.group_based_title_rules
      return if rules_json_string.blank?

      begin
        # 这是最关键的修复:手动将JSON字符串解析成Ruby数组
        rules = JSON.parse(rules_json_string)
      rescue JSON::ParserError
        # 如果JSON格式错误,则直接退出,防止任务失败
        Rails.logger.error("Group-Based Titles Plugin: Failed to parse group_based_title_rules JSON.")
        return
      end
      
      return unless rules.is_a?(Array) && rules.present?

      User.transaction do
        rules.each do |rule|
          group_id = rule["group_id"]
          trust_level = rule["trust_level"]
          title = rule["title"]

          next if group_id.blank? || trust_level.blank? || title.blank?

          User.where(primary_group_id: group_id, trust_level: trust_level)
              .where.not(title: title)
              .update_all(title: title)
        end
      end
    end
  end
end

config/settings.yml

plugins:
  add_title_by_group_trust_enabled:
    default: true
    client: true

  # This MUST be type: objects. This was the source of the error.
  group_based_title_rules:
    type: objects
    default: []
    schema:
      properties:
        group_id:
          type: integer
          name: "User Group"
          component: "group-chooser"
        trust_level:
          type: integer
          name: "Trust Level"
          min: 1
          max: 4
        title:
          type: string
          name: "Title"
  
  update_title_frequency:
    default: 24
    type: integer

plugin.rb

# frozen_string_literal: true

# name: add-title-by-group-trust-level
# about: Assign titles based on primary group and trust level.
# version: 2.1.0
# authors: Your Name

enabled_site_setting :add_title_by_group_trust_enabled

after_initialize do
  require_relative "./app/jobs/scheduled/update-all-titles.rb"
end
1 « J'aime »