class MaterialSyncSuppression < ApplicationRecord SOURCE_KINDS = [ 'uri', 'google_drive_path', 'google_drive_file', 'legacy_drive_path' ].freeze REASONS = [ 'copyright_high_risk', 'copyright_takedown', 'adult_or_sensitive', 'personal_information', 'malware_or_dangerous_file', 'duplicate_or_low_quality', 'source_owner_request', 'other' ].freeze belongs_to :created_by_user, class_name: 'User', optional: true before_validation :assign_normalized_source_key validates :source_kind, presence: true, inclusion: { in: SOURCE_KINDS } validates :reason, presence: true, inclusion: { in: REASONS } validates :normalized_source_key, presence: true, uniqueness: true validate :source_value_must_be_present def self.normalize_source_key source_kind:, source_uri: nil, drive_path: nil, drive_file_id: nil, source_path: nil, source_file_id: nil kind = source_kind.to_s value = case kind when 'uri' source_uri.to_s.strip when 'google_drive_path', 'legacy_drive_path' (source_path || drive_path).to_s.strip.gsub(%r{/+}, '/') when 'google_drive_file' (source_file_id || drive_file_id).to_s.strip else '' end return nil if kind.blank? || value.blank? "#{ kind }:#{ value }" end private def assign_normalized_source_key self.normalized_source_key = self.class.normalize_source_key(source_kind:, source_uri:, drive_path:, drive_file_id:) end def source_value_must_be_present return if normalized_source_key.present? errors.add(:base, '同期元を指定してください.') end end