discourse/app/models/notification.rb

96 lines
2.3 KiB
Ruby
Raw Normal View History

2013-02-06 03:16:51 +08:00
class Notification < ActiveRecord::Base
2013-02-07 23:45:24 +08:00
2013-02-06 03:16:51 +08:00
belongs_to :user
belongs_to :topic
validates_presence_of :data
validates_presence_of :notification_type
def self.Types
{:mentioned => 1,
:replied => 2,
:quoted => 3,
:edited => 4,
2013-02-07 23:45:24 +08:00
:liked => 5,
2013-02-06 03:16:51 +08:00
:private_message => 6,
:invited_to_private_message => 7,
2013-02-07 23:45:24 +08:00
:invitee_accepted => 8,
2013-02-06 03:16:51 +08:00
:posted => 9,
2013-02-07 23:45:24 +08:00
:moved_post => 10}
2013-02-06 03:16:51 +08:00
end
def self.InvertedTypes
@inverted_types ||= Notification.Types.invert
end
def self.unread
2013-02-07 23:45:24 +08:00
where(read: false)
end
2013-02-06 03:16:51 +08:00
def self.mark_post_read(user, topic_id, post_number)
Notification.update_all "read = true", ["user_id = ? and topic_id = ? and post_number = ?", user.id, topic_id, post_number]
end
def self.recent
order('created_at desc').limit(10)
end
def self.interesting_after(min_date)
result = where("created_at > ?", min_date)
.includes(:topic)
.unread
.limit(20)
.order("CASE WHEN notification_type = #{Notification.Types[:replied]} THEN 1
WHEN notification_type = #{Notification.Types[:mentioned]} THEN 2
ELSE 3
END, created_at DESC").to_a
# Remove any duplicates by type and topic
if result.present?
2013-02-07 23:45:24 +08:00
seen = {}
2013-02-06 03:16:51 +08:00
to_remove = Set.new
result.each do |r|
seen[r.notification_type] ||= Set.new
if seen[r.notification_type].include?(r.topic_id)
2013-02-07 23:45:24 +08:00
to_remove << r.id
2013-02-06 03:16:51 +08:00
else
seen[r.notification_type] << r.topic_id
end
end
2013-02-07 23:45:24 +08:00
result.reject! {|r| to_remove.include?(r.id) }
2013-02-06 03:16:51 +08:00
end
result
end
# Be wary of calling this frequently. O(n) JSON parsing can suck.
def data_hash
@data_hash ||= begin
return nil if data.blank?
::JSON.parse(data).with_indifferent_access
end
end
def text_description
link = block_given? ? yield : ""
I18n.t("notification_types.#{Notification.InvertedTypes[notification_type]}", data_hash.merge(link: link))
end
def url
if topic.present?
return topic.relative_url(post_number)
end
nil
end
def post
return nil unless topic_id.present?
return nil unless post_number.present?
Post.where(topic_id: topic_id, post_number: post_number).first
end
end