Migliore pratica per automatizzare i titoli per combinazioni di gruppi e livelli di fiducia

Hi,

I’m looking for the best way to automatically assign user titles based on a combination of group membership and trust level. For example:

  • If a user is in group A and has trust level 1, their title should be “A TL1”
  • If a user is in group A and has trust level 2, their title should be “A TL2”
  • If a user is in group B and has trust level 1, their title should be “B TL1”
  • …and so on

From what I’ve found so far, the main method is:

  1. Create a separate group for each group + trust level combination (e.g. a-tl1, a-tl2, b-tl1, etc) using the Dynamic Groups plugin,
  2. Set a default title for each of these groups.

While this seems to work, it requires creating and maintaining a large number of groups if there are many combinations.

My questions:

  • Is this setup (many dynamic groups and each with its own default title) the best or only way to keep titles in sync automatically?
  • Is there another approach (using Discourse core, Automations, or another plugin) to dynamically assign titles based on conditions like group + trust level, without having to manage so many additional groups?

Any advice or shared experiences would be greatly appreciated. Thanks in advance!

Would it work for you to configure the title based on the group membership (A or B) and have a component that adds the title based on the trust level behind that?

I think then you wouldn’t need all those combined subgroups :thinking:

Another idea: Maybe the plugin which automatically sets the trust level as the title could be used as a base for a more complex title update based on trust level and group membership

3 Mi Piace

Thank you for your suggestions

Unfortunately, I don’t have any programming experience myself, so I’m not able to develop or modify plugins. I have already reached out to the plugin author to ask if this feature (combining group membership and trust level for titles) could be added, or if they have any advice.

If it’s the user’s primary groups, I think as you mentioned in the other topic, that would make things a lot easier.

Then, you can get their primary group via user.primary_group and then set the title using user.title.

@joo I have added the setting add_primary_group_title (default off) that:

  • adds the user’s primary group as the title
  • text behind the title, eg:

         can be edited using the settings as before.

Used a hint of ask.discourse.com magic.

P.S. If you’re wondering how I indented the ‘can’, I used  . Sorry guys.

1 Mi Piace

Hi! Thank you for your update and support!

I may not have explained my requirement clearly before, so I want to clarify it again with an easy-to-understand example:

Suppose our forum has two main groups:

  • Group A: Designers
  • Group B: Developers

For each group, I want users with different trust levels to get a completely different title, like this:

For Designers group:
Trust Level 1 → “Junior Designer”
Trust Level 2 → “Designer”
Trust Level 3 → “Senior Designer”
Trust Level 4 → “Chief Designer”

For Developers group:
Trust Level 1 → “Junior Developer”
Trust Level 2 → “Developer”
Trust Level 3 → “Senior Developer”
Trust Level 4 → “Tech Lead”

So, if someone is in “Designers” with TL3, their title should be “Senior Designer”.
If they are in “Developers” with TL2, the title should be “Developer”.

I would like to be able to set these rules for each group and trust level, and have titles assigned automatically as users’ groups or trust levels change.

Is there any advice you could share on how to achieve this, or would you consider adding this as a new feature in your plugin?

Thank you very much!

1 Mi Piace

Also, I am trying to achieve this on my test site: http://ask.discourse.com/.
I don’t have programming experience, so I am not sure if it’s possible to implement this myself.

I might use a placeholder value, e.g. {group_nane} in the text box so that it can be easier to edit the title. I’ll take a look.

You might want to check out:

Hi!

I’ve modified the plugin to fit my needs, and I’d like to share what I did, my current workflow, and a few questions/requests for advice.


1. My Modifications

File path and content:

File: 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|
        # Skip admins and moderators, do not update their titles
        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

File: 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. How I Tested

I am currently manually running this logic via rails console to check if the function works. It does update user titles in bulk according to my requirements.


3. Plugin Settings Entry Issue

There is no “Settings” button for this plugin on the /admin/plugins page. Right now, to change the config, I have to visit /admin/plugins/add-title-based-on-trust-level/settings directly.
Is there a way to have the settings button or link appear on the Plugins page for easier access?


4. My Current Settings

This is my current JSON configuration (I will attach a screenshot as well):

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


5. Questions / Possible Improvements

  • Does this approach (looping through every user and updating their title) risk performance issues if there are a lot of users? Is there a better best-practice for this?
  • Any advice on optimization, either for the scheduled job or for the admin settings UI?
  • Is there anything unsafe or problematic with my method that I should be careful about?

Thank you very much for your great work and this useful plugin!
If you have any suggestions, or if you plan to improve group+trust level title config in the future, I would love to hear your thoughts.

2 Mi Piace

@joo Really neat idea!

If you look at the plugin now, I think I did this too (was running some final tests). I see you looped through each user, but in big forums, this may take a while.

So, I did a SQL UPDATE:

(I adapted Ask Discourse’s query and modified it)

This way, in the setting tl1_title_on_promotion, you should be able to use something like Junior {group_name}, so then the title would become Junior Developer.

Note that you would also have to tick add_primary_group_title for it to work.

1 Mi Piace

Thanks for the explanation, I understand how your {group_name} template works now.

But this is exactly what I meant by the difference in logic. My core requirement is to be able to apply completely different title structures for the same trust level, based on different user groups.

For example, for Trust Level 3:

  • The title for the “Designers” group should be “Senior Designer”.
  • The title for the “Developers” group should be “Tech Lead”.

These two titles have completely different structures.

I tried to implement this feature with an AI, but I wasn’t successful. I was wondering if it might be possible for you to modify the plugin to support this more granular logic?

Ah, I think I misunderstood you then.

So did your code above work?

No, the previous code I tried with an AI didn’t work either. After setting everything up, nothing happened at all.

I wanted to show you the full code from my latest attempt. I was hoping you might be able to see what I’m doing wrong.

1. plugin.rb

# name: add-title-by-group-trust-level
# about: assign titles via primary group + trust level using SQL
# version: 0.2
# authors: your-name

# Note: I'm not sure if I need a 'require' line here to load the job file.
# I suspect this might be the missing piece.
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

Here’s how I configured it in the Site Settings:

I pasted this JSON into the group_trust_level_titles setting:

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

The Problem:

The UpdateTitles job doesn’t appear in the Sidekiq scheduler (/sidekiq/scheduler).

However, I tested it in the Rails console according to the method the AI gave me, and the core logic is perfectly fine, correctly printing out all the users who meet the conditions.

This is the test script I used in the Rails console:

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 "Could not find group: #{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 "====== Group: #{group.name} Trust Level: #{tl} New Title: '#{title}' ======"
    users.each do |user|
      puts "User id:#{user.id}, username:#{user.username}, current title:'#{user.title}'"
    end
  end
end

So it seems the logic itself is correct, but Discourse isn’t registering the scheduled job. Anyway, the more I try to change it, the more confusing it gets… I’m not sure if this is the right approach, and since I don’t know how to code, it feels very difficult to implement this. Do you have a better method?

Hmm… maybe you want to use object settings:

With fields like Trust Level, group, title.

1 Mi Piace

Just wanted to give an update and say thank you to everyone who helped.

With the latest changes, the plugin is now working exactly as I intended! It correctly assigns different titles based on the user’s primary group and trust level.

I’m posting the final working code below. It seems to be correct, but since I’m not a developer, I was wondering if there are any areas for improvement or optimization that I might have missed.

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

      rules_json_string = SiteSetting.group_based_title_rules
      return if rules_json_string.blank?

      begin
        # Manually parse the JSON string into a Ruby array.
        rules = JSON.parse(rules_json_string)
      rescue JSON::ParserError
        # If the JSON is malformed, log an error and exit to prevent the job from failing.
        Rails.logger.error("Group-Based Titles Plugin: Failed to parse group_based_title_rules JSON.")
        return
      end
      
      # Safety check to ensure the parsed rules are a non-empty array.
      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

  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 Mi Piace