FEATURE: Allow multiple required tag groups for a category (#16381)

Previously we only supported a single 'required tag group' for a category. This commit allows admins to specify multiple required tag groups, each with their own minimum tag count.

A new category_required_tag_groups database table replaces the existing columns on the categories table. Data is automatically migrated.
This commit is contained in:
David Taylor
2022-04-06 14:08:06 +01:00
committed by GitHub
parent 8f03baaf8e
commit 68c74e9b93
32 changed files with 387 additions and 156 deletions

View File

@ -5,10 +5,11 @@ class Category < ActiveRecord::Base
'none'
]
# TODO(2020-11-18): remove
self.ignored_columns = %w{
suppress_from_latest
}
self.ignored_columns = [
:suppress_from_latest, # TODO(2020-11-18): remove
:required_tag_group_id, # TODO(2023-04-01): remove
:min_tags_from_required_group, # TODO(2023-04-01): remove
]
include Searchable
include Positionable
@ -56,7 +57,6 @@ class Category < ActiveRecord::Base
validates :num_featured_topics, numericality: { only_integer: true, greater_than: 0 }
validates :search_priority, inclusion: { in: Searchable::PRIORITIES.values }
validates :min_tags_from_required_group, numericality: { only_integer: true, greater_than: 0 }
validate :parent_category_validator
validate :email_in_validator
@ -103,7 +103,8 @@ class Category < ActiveRecord::Base
has_many :tags, through: :category_tags
has_many :category_tag_groups, dependent: :destroy
has_many :tag_groups, through: :category_tag_groups
belongs_to :required_tag_group, class_name: 'TagGroup'
has_many :category_required_tag_groups, -> { order(order: :asc) }, dependent: :destroy
belongs_to :reviewable_by_group, class_name: 'Group'
@ -639,8 +640,14 @@ class Category < ActiveRecord::Base
self.tag_groups = TagGroup.where(name: group_names).all.to_a
end
def required_tag_group_name=(group_name)
self.required_tag_group = group_name.blank? ? nil : TagGroup.where(name: group_name).first
def required_tag_groups=(required_groups)
map = Array(required_groups).map.with_index { |rg, i| [rg["name"], { min_count: rg["min_count"].to_i, order: i }] }.to_h
tag_groups = TagGroup.where(name: map.keys)
self.category_required_tag_groups = tag_groups.map do |tag_group|
attrs = map[tag_group.name]
CategoryRequiredTagGroup.new(tag_group: tag_group, **attrs)
end.sort_by(&:order)
end
def downcase_email
@ -1044,8 +1051,6 @@ end
# search_priority :integer default(0)
# allow_global_tags :boolean default(FALSE), not null
# reviewable_by_group_id :integer
# required_tag_group_id :integer
# min_tags_from_required_group :integer default(1), not null
# read_only_banner :string
# default_list_filter :string(20) default("all")
# allow_unlimited_owner_edits_on_first_post :boolean default(FALSE), not null