has_translations.rb 1.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364
  1. # Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/
  2. module HasTranslations
  3. extend ActiveSupport::Concern
  4. included do
  5. has_many :translations, class_name: translation_class_name, # rubocop:disable Rails/ReflectionClassName
  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
  44. .to_a
  45. .reject(&:valid?)
  46. .each do |elem|
  47. error_key = elem.errors.keys.first
  48. errors.add "translations.#{error_key}", elem.errors.messages[error_key].first
  49. end
  50. end
  51. end