mirror of
https://gh.wpcy.net/https://github.com/discourse/discourse.git
synced 2026-05-02 08:13:47 +08:00
Related:
https://meta.discourse.org/t/yet-another-title-localization-issue/395469
### bug context
tldr; `Topic#fancy_title` saves a fancy_title to db when the fancy_title
is null.
This bug requires a certain incantation to trigger.
- Topic 395465 exists with `title = "Notification level button always
says \"tracking\""` and
`fancy_title = NULL` in the DB
- A `TopicLocalization` exists for this topic in `zh_CN`
- `content_localization_enabled` is on
When a crawler hits `GET /t/.../395465?tl=zh_CN`, localization
replacement happens on the topic, which writes the title attribute, so
the state is now
- `title` = Chinese (modified)
- `fancy_title` = NULL (untouched, still what was loaded from DB)
When serializing via `TopicViewSerializer` which uses
`LocalizedFancyTopicTitleMixin`, we call `topic.fancy_title`. The
`topic#fancy_title` generates the fancy_title from the title value, then
writes the chinese fancy title to db 😢
e935ed63b2/app/models/topic.rb (L532-L545)
### fix
This commit fixes the issue by ensuring the fancy_title is always written
along with the title, preventing the need for invoking
`topic#fancy_title`.
47 lines
1.6 KiB
Ruby
47 lines
1.6 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
module LocalizationAttributesReplacer
|
|
def self.replace_category_attributes(category, crawl_locale)
|
|
if loc = get_localization(category, crawl_locale)
|
|
category.name = loc.name if loc.name.present?
|
|
category.description = loc.description if loc.description.present?
|
|
end
|
|
|
|
while category = category.parent_category
|
|
replace_category_attributes(category, crawl_locale)
|
|
end
|
|
end
|
|
|
|
def self.replace_topic_attributes(topic, crawl_locale)
|
|
if loc = get_localization(topic, crawl_locale)
|
|
# assigning directly to title would commit the change to the database
|
|
# due to the setter method defined in the Topic model.
|
|
# fancy_title must also be set to prevent the lazy DB write in
|
|
# Topic#fancy_title from persisting a localized value when fancy_title is NULL.
|
|
if loc.title.present?
|
|
topic.send(:write_attribute, :title, loc.title)
|
|
topic.send(
|
|
:write_attribute,
|
|
:fancy_title,
|
|
loc.fancy_title.presence || Topic.fancy_title(loc.title),
|
|
)
|
|
end
|
|
topic.excerpt = loc.excerpt if loc.excerpt.present?
|
|
end
|
|
|
|
replace_category_attributes(topic.category, crawl_locale) if topic&.category.present?
|
|
end
|
|
|
|
def self.replace_post_attributes(post, crawl_locale)
|
|
if loc = get_localization(post, crawl_locale)
|
|
post.cooked = loc.cooked if loc.cooked.present?
|
|
end
|
|
end
|
|
|
|
private
|
|
|
|
def self.get_localization(model, crawl_locale)
|
|
model.present? && model.locale.present? &&
|
|
!LocaleNormalizer.is_same?(model.locale, crawl_locale) && model.get_localization(crawl_locale)
|
|
end
|
|
end
|