Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2020-12-04 15:09:39 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2020-12-04 15:09:39 +0300
commit8322f051740fba113c5c1f6fba96b9c943240746 (patch)
treebc695dfd5538f9378041f4a4fa6bd097ecf58954 /app/models/concerns/cache_markdown_field.rb
parentf9fe7cda4bdbc477d8d76e5def4023f7d03bab46 (diff)
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app/models/concerns/cache_markdown_field.rb')
-rw-r--r--app/models/concerns/cache_markdown_field.rb62
1 files changed, 59 insertions, 3 deletions
diff --git a/app/models/concerns/cache_markdown_field.rb b/app/models/concerns/cache_markdown_field.rb
index 49fc780f372..45944401c2d 100644
--- a/app/models/concerns/cache_markdown_field.rb
+++ b/app/models/concerns/cache_markdown_field.rb
@@ -70,8 +70,12 @@ module CacheMarkdownField
def refresh_markdown_cache!
updates = refresh_markdown_cache
-
- save_markdown(updates)
+ if updates.present? && save_markdown(updates)
+ # save_markdown updates DB columns directly, so compute and save mentions
+ # by calling store_mentions! or we end-up with missing mentions although those
+ # would appear in the notes, descriptions, etc in the UI
+ store_mentions! if mentionable_attributes_changed?(updates)
+ end
end
def cached_html_up_to_date?(markdown_field)
@@ -106,7 +110,19 @@ module CacheMarkdownField
def updated_cached_html_for(markdown_field)
return unless cached_markdown_fields.markdown_fields.include?(markdown_field)
- refresh_markdown_cache! if attribute_invalidated?(cached_markdown_fields.html_field(markdown_field))
+ if attribute_invalidated?(cached_markdown_fields.html_field(markdown_field))
+ # Invalidated due to Markdown content change
+ # We should not persist the updated HTML here since this will depend on whether the
+ # Markdown content change will be persisted. Both will be persisted together when the model is saved.
+ if changed_attributes.key?(markdown_field)
+ refresh_markdown_cache
+ else
+ # Invalidated due to stale HTML cache
+ # This could happen when the Markdown cache version is bumped or when a model is imported and the HTML is empty.
+ # We persist the updated HTML here so that subsequent calls to this method do not have to regenerate the HTML again.
+ refresh_markdown_cache!
+ end
+ end
cached_html_for(markdown_field)
end
@@ -140,6 +156,46 @@ module CacheMarkdownField
nil
end
+ def store_mentions!
+ refs = all_references(self.author)
+
+ references = {}
+ references[:mentioned_users_ids] = refs.mentioned_users&.pluck(:id).presence
+ references[:mentioned_groups_ids] = refs.mentioned_groups&.pluck(:id).presence
+ references[:mentioned_projects_ids] = refs.mentioned_projects&.pluck(:id).presence
+
+ # One retry is enough as next time `model_user_mention` should return the existing mention record,
+ # that threw the `ActiveRecord::RecordNotUnique` exception in first place.
+ self.class.safe_ensure_unique(retries: 1) do
+ user_mention = model_user_mention
+
+ # this may happen due to notes polymorphism, so noteable_id may point to a record
+ # that no longer exists as we cannot have FK on noteable_id
+ break if user_mention.blank?
+
+ user_mention.mentioned_users_ids = references[:mentioned_users_ids]
+ user_mention.mentioned_groups_ids = references[:mentioned_groups_ids]
+ user_mention.mentioned_projects_ids = references[:mentioned_projects_ids]
+
+ if user_mention.has_mentions?
+ user_mention.save!
+ else
+ user_mention.destroy!
+ end
+ end
+
+ true
+ end
+
+ def mentionable_attributes_changed?(changes = saved_changes)
+ return false unless is_a?(Mentionable)
+
+ self.class.mentionable_attrs.any? do |attr|
+ changes.key?(cached_markdown_fields.html_field(attr.first)) &&
+ changes.fetch(cached_markdown_fields.html_field(attr.first)).last.present?
+ end
+ end
+
included do
cattr_reader :cached_markdown_fields do
Gitlab::MarkdownCache::FieldData.new