Module: SimpleNotifications::Base

Defined in:
lib/simple_notifications/base.rb

Instance Method Summary collapse

Instance Method Details

#notified?Boolean

Getter to check if model is enabled with notifications



6
7
8
# File 'lib/simple_notifications/base.rb', line 6

def notified?
  !!@@notified_flag
end

#notify(options = {}) ⇒ Object

Example notify(sender: :author, receivers: :followers)



12
13
14
15
16
17
18
19
20
21
22
23
24
# File 'lib/simple_notifications/base.rb', line 12

def notify(options = {})
  @@entity_class = self
  @@sender = options[:sender]
  @@receivers = options[:receivers]
  SimpleNotifications::Record.before_notify = options[:before_notify] if !!options[:before_notify]
  SimpleNotifications::Record.after_notify = options[:after_notify] if !!options[:after_notify]

  open_sender_class
  open_receiver_class
  open_notified_class

  @@notified_flag = true
end

#open_notified_classObject

Opening the class on which the notify functionality is applied.



46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
# File 'lib/simple_notifications/base.rb', line 46

def open_notified_class
  class_eval do
    attr_accessor :message, :notify
    # Define association for the notified model
    has_many :notifications, class_name: 'SimpleNotifications::Record', as: :entity
    has_many :notifiers, through: :notifications, source: :sender, source_type: sender_class(@@sender).to_s

    # Opening the Notification class.
    SimpleNotifications::Record.class_eval do
      [@@entity_class.receivers_class(@@receivers)].flatten.each do |receiver_class|
        has_many "#{receiver_class.name.downcase}_receivers".to_sym,
                 through: :deliveries,
                 source: :receiver,
                 source_type: receiver_class.name
      end
    end

    [receivers_class(@@receivers)].flatten.each do |receiver_class|
      has_many "#{receiver_class.name.downcase}_notificants".to_sym,
               through: :notifications,
               source: "#{receiver_class.name.downcase}_receivers".to_sym
    end

    has_many :read_deliveries, through: :notifications, source: :read_deliveries
    has_many :unread_deliveries, through: :notifications, source: :unread_deliveries
    # has_many :notificants, through: :notifications, source: :receivers
    # has_many :read_notificants, through: :read_deliveries, source: :receiver, source_type: 'User'
    # has_many :unread_notificants, through: :unread_deliveries, source: :receiver, source_type: 'User'

    # Callbacks
    after_create_commit :create_notification, if: proc {@notify.nil? || !!@notify}
    after_update_commit :update_notification, if: proc {@notify.nil? || !!@notify}

    # Check if notifications has already been delivered.
    def notified?
      !notifications.blank?
    end

    #Example
    #post.notify(sender: :author, receivers: :followers, message: 'My Custom logic message')
    #post.create(content: '', notify: false) -> It does not create the notification.
    def notify(options = {})
      raise 'SimpleNotification::SenderReceiverError' unless options[:sender] && options[:receivers]
      @message = options[:message] if options[:message]
      notification = notifications.build(entity: self, sender: options[:sender],
                                         message: default_message(self, options[:sender], 'created'))
      options[:receivers].each {|receiver| notification.deliveries.build(receiver: receiver)}
      notification.save
    end

    def notificants
      #TODO : Need to eager load
      SimpleNotifications::Record.where(entity: self).collect {|notification| notification.deliveries.collect(&:receiver)}.flatten
    end

    def read_marked_notificants
      #TODO : Need to eager load
      SimpleNotifications::Record.where(entity: self).collect {|notification| notification.deliveries.where(is_read: true).collect(&:receiver)}.flatten
    end

    def unread_marked_notificants
      #TODO : Need to eager load
      SimpleNotifications::Record.where(entity: self).collect {|notification| notification.deliveries.where(is_read: false).collect(&:receiver)}.flatten
    end

    # Mark notifications in read mode.
    # If notificants are provided then only those respective notifications will be marked read.
    # Else all will be marked as read.
    def mark_read(notificants = nil)
      (notificants ? unread_deliveries.where(receiver: notificants) : unread_deliveries).update_all(is_read: true)
    end

    # Mark notifications in unread mode.
    # If notificants are provided then only those respective notifications will be marked unread.
    # Else all will be marked as unread.
    def mark_unread(notificants = nil)
      (notificants ? read_deliveries.where(receiver: notificants) : read_deliveries).update_all(is_read: false)
    end

    private

    def get_obj(sender_or_receivers)
      sender_or_receivers.kind_of?(Symbol) ? send(sender_or_receivers) : sender_or_receivers
    end

    def default_message(entity, sender, action)
      @message || "#{entity.class.name} #{entity.name} #{action}."
    end

    def create_notification
      notify({sender: get_obj(@@sender), receivers: get_obj(@@receivers), message: default_message(self, get_obj(@@sender), 'created')})
    end

    def update_notification
      notify({sender: get_obj(@@sender), receivers: get_obj(@@receivers), message: default_message(self, get_obj(@@sender), 'updated')})
    end
  end
end

#open_receiver_classObject

Opening the classes which are defined as receivers.



35
36
37
38
39
40
41
42
43
# File 'lib/simple_notifications/base.rb', line 35

def open_receiver_class
  # Define association for receiver model
  [receivers_class(@@receivers)].flatten.each do |base|
    base.class_eval do
      has_many :deliveries, class_name: 'SimpleNotifications::Delivery', as: :receiver
      has_many :received_notifications, through: :deliveries, source: :simple_notification
    end
  end
end

#open_sender_classObject

Opening the class which is defined as sender.



27
28
29
30
31
32
# File 'lib/simple_notifications/base.rb', line 27

def open_sender_class
  # Define association for sender model
  sender_class(@@sender).class_eval do
    has_many :sent_notifications, class_name: 'SimpleNotifications::Record', as: :sender
  end
end

#receivers_class(receivers) ⇒ Object

Provides the classes of Receivers



157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
# File 'lib/simple_notifications/base.rb', line 157

def receivers_class(receivers)
  if receivers.kind_of? Symbol
    reflections[receivers.to_s].klass
  else
    if receivers.kind_of? ActiveRecord::Base
      receivers.class
    elsif receivers.kind_of? ActiveRecord::Relation
      receivers.klass
    elsif receivers.kind_of? Array
      receivers.flatten.collect {|receiver| receivers_class(receiver)}
    else
      raise 'SimpleNotifications::ReceiverTypeError'
    end
  end
end

#sender_class(sender) ⇒ Object

Provides the class of Sender



146
147
148
149
150
151
152
153
154
# File 'lib/simple_notifications/base.rb', line 146

def sender_class(sender)
  if sender.kind_of? Symbol
    reflections[sender.to_s].klass
  elsif sender.kind_of? ActiveRecord::Base
    sender.class
  else
    raise 'SimpleNotifications::SenderTypeError'
  end
end