about summary refs log tree commit diff
path: root/app/models/featured_tag.rb
diff options
context:
space:
mode:
authorEugen Rochko <eugen@zeonfederated.com>2022-07-13 15:03:28 +0200
committerGitHub <noreply@github.com>2022-07-13 15:03:28 +0200
commite7aa2be828f6a632dadd5c41e2364cea91ddbb2c (patch)
treef18390c05c4aa6ce5b15572b470db4bd4791129b /app/models/featured_tag.rb
parent12ed2d793b1b4823b0df047a47677bb0667bf43d (diff)
Change how hashtags are normalized (#18795)
* Change how hashtags are normalized

* Fix tests
Diffstat (limited to 'app/models/featured_tag.rb')
-rw-r--r--app/models/featured_tag.rb31
1 files changed, 21 insertions, 10 deletions
diff --git a/app/models/featured_tag.rb b/app/models/featured_tag.rb
index 74d62e777..c9c285bfa 100644
--- a/app/models/featured_tag.rb
+++ b/app/models/featured_tag.rb
@@ -13,17 +13,19 @@
 #
 
 class FeaturedTag < ApplicationRecord
-  belongs_to :account, inverse_of: :featured_tags, required: true
-  belongs_to :tag, inverse_of: :featured_tags, required: true
+  belongs_to :account, inverse_of: :featured_tags
+  belongs_to :tag, inverse_of: :featured_tags, optional: true # Set after validation
 
-  delegate :name, to: :tag, allow_nil: true
-
-  validates_associated :tag, on: :create
-  validates :name, presence: true, on: :create
+  validate :validate_tag_name, on: :create
   validate :validate_featured_tags_limit, on: :create
 
-  def name=(str)
-    self.tag = Tag.find_or_create_by_names(str.strip)&.first
+  before_create :set_tag
+  before_create :reset_data
+
+  attr_writer :name
+
+  def name
+    tag_id.present? ? tag.name : @name
   end
 
   def increment(timestamp)
@@ -34,14 +36,23 @@ class FeaturedTag < ApplicationRecord
     update(statuses_count: [0, statuses_count - 1].max, last_status_at: account.statuses.where(visibility: %i(public unlisted)).tagged_with(tag).where.not(id: deleted_status_id).select(:created_at).first&.created_at)
   end
 
+  private
+
+  def set_tag
+    self.tag = Tag.find_or_create_by_names(@name)&.first
+  end
+
   def reset_data
     self.statuses_count = account.statuses.where(visibility: %i(public unlisted)).tagged_with(tag).count
     self.last_status_at = account.statuses.where(visibility: %i(public unlisted)).tagged_with(tag).select(:created_at).first&.created_at
   end
 
-  private
-
   def validate_featured_tags_limit
     errors.add(:base, I18n.t('featured_tags.errors.limit')) if account.featured_tags.count >= 10
   end
+
+  def validate_tag_name
+    errors.add(:name, :blank) if @name.blank?
+    errors.add(:name, :invalid) unless @name.match?(/\A(#{Tag::HASHTAG_NAME_RE})\z/i)
+  end
 end