mention.rb 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. # Copyright (C) 2012-2025 Zammad Foundation, https://zammad-foundation.org/
  2. class Mention < ApplicationModel
  3. include HasDefaultModelUserRelations
  4. include ChecksClientNotification
  5. include HasHistory
  6. include Mention::Assets
  7. # used to forward the sourceable to the mention model
  8. # to keep track of added and removed mention by
  9. # postmaster filters, triggers and schedulers
  10. attr_accessor :sourceable
  11. after_create :update_mentionable
  12. after_destroy :update_mentionable
  13. belongs_to :user, class_name: 'User'
  14. belongs_to :mentionable, polymorphic: true
  15. association_attributes_ignored :created_by, :updated_by
  16. client_notification_events_ignored :update, :touch
  17. validates_with Validations::MentionValidator
  18. def notify_clients_data_attributes
  19. super.merge(
  20. 'mentionable_id' => mentionable_id,
  21. 'mentionable_type' => mentionable_type,
  22. )
  23. end
  24. def history_log_attributes
  25. {
  26. related_o_id: mentionable_id,
  27. related_history_object: mentionable_type,
  28. value_to: user.id,
  29. sourceable:,
  30. }
  31. end
  32. def history_destroy
  33. history_log('removed', created_by_id)
  34. end
  35. def self.duplicates(mentionable1, mentionable2)
  36. Mention.joins(', mentions as mentionsb').where('
  37. mentions.user_id = mentionsb.user_id
  38. AND mentions.mentionable_type = ?
  39. AND mentions.mentionable_id = ?
  40. AND mentionsb.mentionable_type = ?
  41. AND mentionsb.mentionable_id = ?
  42. ', mentionable1.class.to_s, mentionable1.id, mentionable2.class.to_s, mentionable2.id)
  43. end
  44. def update_mentionable
  45. # make sure mentionable is touched even if updated_by value stays the same
  46. mentionable.update(updated_by: updated_by, updated_at: Time.current)
  47. end
  48. # Check if user is subscribed to given object
  49. # @param target to check against
  50. # @param user
  51. # @return Boolean
  52. def self.subscribed?(object, user)
  53. object.mentions.exists? user: user
  54. end
  55. # Subscribe a user to changes of an object
  56. # @param target to subscribe to
  57. # @param user
  58. # @return Boolean
  59. def self.subscribe!(object, user, sourceable: nil)
  60. object.mentions.create!(user: user, sourceable: sourceable) if !subscribed?(object, user)
  61. true
  62. end
  63. # Unsubscribe a user from changes of an object
  64. # @param target to unsubscribe from
  65. # @param user
  66. # @return Boolean
  67. def self.unsubscribe!(object, user, sourceable: nil)
  68. mention = object.mentions.find_by(user:)
  69. return true if mention.blank?
  70. mention.sourceable = sourceable
  71. mention.destroy!
  72. true
  73. end
  74. # Unsubscribe all users from changes of an object
  75. # @param target to unsubscribe from
  76. # @return Boolean
  77. def self.unsubscribe_all!(object, sourceable: nil)
  78. return object.mentions.destroy_all if sourceable.blank?
  79. object.mentions.all? do |mention|
  80. mention.sourceable = sourceable
  81. mention.destroy!
  82. end
  83. end
  84. # Check if given user is able to subscribe to a given object
  85. # @param object to subscribe to
  86. # @param mentioned user
  87. # @return Boolean
  88. def self.mentionable?(object, user)
  89. case object
  90. when Ticket
  91. TicketPolicy.new(user, object).agent_read_access?
  92. else
  93. false
  94. end
  95. end
  96. end