FIX: Permalink.create didn't work as expected anymore (#29895)

This moves the logic of setting the correct permalink values back into the controller. And it replaces the validation with a simpler one, that always works, even when the model is loaded from the DB.

Follow-up to #29634 which broke import scripts and lots of documentation on Meta.
This commit is contained in:
Gerhard Schlager
2024-11-22 21:11:26 +01:00
committed by GitHub
parent 44fbf1048c
commit 0295b4165c
9 changed files with 78 additions and 216 deletions

View File

@ -1,30 +1,16 @@
# frozen_string_literal: true
class Permalink < ActiveRecord::Base
attr_accessor :permalink_type, :permalink_type_value
belongs_to :topic
belongs_to :post
belongs_to :category
belongs_to :tag
belongs_to :user
before_validation :clear_associations
before_validation :normalize_url, :encode_url
before_validation :set_association_value
validates :url, uniqueness: true
validates :topic_id, presence: true, if: Proc.new { |permalink| permalink.topic_type? }
validates :post_id, presence: true, if: Proc.new { |permalink| permalink.post_type? }
validates :category_id, presence: true, if: Proc.new { |permalink| permalink.category_type? }
validates :tag_id, presence: true, if: Proc.new { |permalink| permalink.tag_type? }
validates :user_id, presence: true, if: Proc.new { |permalink| permalink.user_type? }
validates :external_url, presence: true, if: Proc.new { |permalink| permalink.external_url_type? }
%i[topic post category tag user external_url].each do |association|
define_method("#{association}_type?") { self.permalink_type == association.to_s }
end
validate :exactly_one_association
class Normalizer
attr_reader :source
@ -114,22 +100,14 @@ class Permalink < ActiveRecord::Base
external_url.match?(%r{\A/[^/]}) ? "#{Discourse.base_path}#{external_url}" : external_url
end
def clear_associations
self.topic_id = nil
self.post_id = nil
self.category_id = nil
self.user_id = nil
self.tag_id = nil
self.external_url = nil
end
def set_association_value
self.topic_id = self.permalink_type_value if self.topic_type?
self.post_id = self.permalink_type_value if self.post_type?
self.user_id = self.permalink_type_value if self.user_type?
self.category_id = self.permalink_type_value if self.category_type?
self.external_url = self.permalink_type_value if self.external_url_type?
self.tag_id = Tag.where(name: self.permalink_type_value).first&.id if self.tag_type?
def exactly_one_association
associations = [topic_id, post_id, category_id, tag_id, user_id, external_url]
if associations.compact.size != 1
errors.add(
:base,
"Exactly one of topic_id, post_id, category_id, tag_id, user_id, or external_url must be set",
)
end
end
end