85 lines
2.7 KiB
Ruby
85 lines
2.7 KiB
Ruby
class Notification
|
|
include Mongoid::Document
|
|
include Mongoid::Timestamps
|
|
include Usernameable
|
|
|
|
after_initialize :set_defaults
|
|
|
|
field :kind, type: String
|
|
field :encrypted_user_id, type: String, encrypted: {type: :integer}
|
|
field :encrypted_notify_user_id, type: String, encrypted: {type: :integer}
|
|
field :delivered, type: Boolean, default: false
|
|
field :post_id, type: String
|
|
field :unread, type: Boolean, default: true
|
|
|
|
validates :notificateable, :encrypted_user_id, :encrypted_notify_user_id, presence: true
|
|
|
|
belongs_to :notificateable, polymorphic: true
|
|
|
|
index notificateable_id: 1, notificateable_type: 1
|
|
|
|
def set_defaults
|
|
assign_attributes(post_id: ((notificateable._type == "Comment") ? notificateable.post_id : notificateable.id).to_s)
|
|
end
|
|
|
|
class << self
|
|
def aggregated_by_kind_and_subject
|
|
group = {}
|
|
|
|
each do |n|
|
|
key = [n.kind, n.notificateable_id.to_s, n.notificateable_type.downcase]
|
|
|
|
group[key] ||= []
|
|
group[key] << n
|
|
end
|
|
|
|
normalized_notifications(group)
|
|
end
|
|
|
|
def count_by_types
|
|
group = criteria.group(_id: "$kind", count: {"$sum": 1})
|
|
aggregate = collection.aggregate(group.pipeline)
|
|
aggregate.reduce({}) { |acc, notification|
|
|
h = {notification["_id"] => notification["count"]}
|
|
acc.merge(h)
|
|
}
|
|
end
|
|
|
|
def groupped_by_post_and_kind(encrypted_user_id)
|
|
where(encrypted_notify_user_id: encrypted_user_id)
|
|
.group_by(&:post_id).deep_transform_keys!(&:to_s)
|
|
.each_with_object({}) { |obj, hash| hash[obj[0]] = aggregate_group(obj[1].group_by(&:kind)) }
|
|
end
|
|
|
|
private
|
|
|
|
def normalized_notifications(group)
|
|
group.map do |group_keys, notifications|
|
|
notificateable = notifications.first.notificateable
|
|
is_comment = notificateable._type == "Comment"
|
|
|
|
{
|
|
id: [notifications.map(&:created_at).max.to_i].concat(group_keys).join("_"),
|
|
kind: group_keys.first,
|
|
count: notifications.count,
|
|
post_id: is_comment ? notificateable.post_id.to_s : group_keys[1],
|
|
post_title: (is_comment ? notificateable.post : notificateable)&.title,
|
|
notificateable_id: group_keys[1],
|
|
notificateable_type: group_keys.last,
|
|
unread: notifications.map(&:unread).last,
|
|
notifier_username: notifier_username(notifications)
|
|
}
|
|
end
|
|
end
|
|
|
|
def aggregate_group(groupped_by_kind)
|
|
groupped_by_kind.each_with_object({}) { |kind, hash| hash[kind[0]] = kind[1].count }
|
|
end
|
|
|
|
def notifier_username(notifications)
|
|
notifier_user_id = SymmetricEncryption.decrypt(notifications.first.encrypted_user_id)
|
|
Profile.find_by(user_id: notifier_user_id)&.screen_name
|
|
end
|
|
end
|
|
end
|