has_translations.rb 1.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263
  1. # Copyright (C) 2012-2024 Zammad Foundation, https://zammad-foundation.org/
  2. module HasTranslations
  3. extend ActiveSupport::Concern
  4. included do
  5. has_many :translations, class_name: translation_class_name,
  6. inverse_of: name.demodulize.underscore,
  7. dependent: :destroy
  8. validate :validate_translations
  9. accepts_nested_attributes_for :translations
  10. # returns objects with single translation according to given locale.
  11. # If no locale is given, defaults to Knowledge Base's primary locale
  12. scope :localed, lambda { |system_locale_or_id|
  13. output = eager_load(:translations).joins(translations: { kb_locale: :knowledge_base })
  14. if system_locale_or_id.present?
  15. output.where('knowledge_base_locales.system_locale_id' => system_locale_or_id)
  16. else
  17. output.where('knowledge_base_locales.system_locale_id' => -1)
  18. end
  19. }
  20. end
  21. def translation
  22. translations.first
  23. end
  24. def translation_to(kb_locale_or_id)
  25. translations.find_by(kb_locale_id: kb_locale_or_id)
  26. end
  27. def translation_preferred(kb_locale_or_id)
  28. translation_to(kb_locale_or_id) || translation_primary || translations.first
  29. end
  30. def translation_primary
  31. translations.joins(:kb_locale).find_by(knowledge_base_locales: { primary: true })
  32. end
  33. class_methods do
  34. def translation_class_name
  35. "#{name}::Translation"
  36. end
  37. def translation_class
  38. translation_class_name.constantize
  39. end
  40. end
  41. private
  42. def validate_translations
  43. translations.reject(&:valid?).each do |elem|
  44. elem.errors.each do |error|
  45. errors.add "translations.#{error.attribute}", error.message
  46. end
  47. end
  48. end
  49. end