has_group_relation_definition.rb 1.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465
  1. # Copyright (C) 2012-2024 Zammad Foundation, https://zammad-foundation.org/
  2. module HasGroupRelationDefinition
  3. extend ActiveSupport::Concern
  4. included do
  5. self.table_name = "groups_#{group_relation_model_identifier}s"
  6. self.primary_key = ref_key, :group_id, :access
  7. belongs_to group_relation_model_identifier, optional: true
  8. belongs_to :group, optional: true
  9. validates :access, presence: true
  10. validate :validate_access
  11. after_commit :touch_related
  12. end
  13. private
  14. def group_relation_instance
  15. @group_relation_instance ||= send(group_relation_model_identifier)
  16. end
  17. def group_relation_model_identifier
  18. @group_relation_model_identifier ||= self.class.group_relation_model_identifier
  19. end
  20. def touch_related
  21. # rubocop:disable Rails/SkipsModelValidations
  22. group.touch if group&.persisted?
  23. group_relation_instance.touch if group_relation_instance&.persisted?
  24. # rubocop:enable Rails/SkipsModelValidations
  25. end
  26. def validate_access
  27. query = self.class.where(
  28. group_relation_model_identifier => group_relation_instance,
  29. group: group
  30. )
  31. query = if access == 'full'
  32. query.where.not(access: 'full')
  33. else
  34. query.where(access: 'full')
  35. end
  36. return if !query.exists?
  37. errors.add(:access, __('%{model} can have full or granular access to group'), model: group_relation_model_identifier.to_s.capitalize)
  38. end
  39. # methods defined here are going to extend the class, not the instance of it
  40. class_methods do
  41. def group_relation_model_identifier
  42. @group_relation_model_identifier ||= model_name.singular.split('_').first.to_sym
  43. end
  44. def ref_key
  45. @ref_key ||= :"#{group_relation_model_identifier}_id"
  46. end
  47. end
  48. end