Module: SimpleNotifications::Base

Defined in:
lib/simple_notifications/base.rb,
lib/simple_notifications/notification_actions.rb

Defined Under Namespace

Modules: NotificationActions

Instance Method Summary collapse

Instance Method Details

#notified?Boolean

Getter to check if model is enabled with notifications

Returns:

  • (Boolean)


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

def notified?
  !!@@notified_flag
end

#notify(options = {}) ⇒ Object

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

receivers: :variants,
action: [:follow, :update, :create, :destroy]


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

def notify(options = {})
  @@entity_class = self
  @@sender = options[:sender]
  @@receivers = options[:receivers]
  @@actions = options[:actions]
  @@notify_message = options[:notify_message]

  SimpleNotifications::Record.before_notify = options[:before_notify] if !!options[:before_notify]
  SimpleNotifications::Record.after_notify = options[:after_notify] if !!options[:after_notify]
  SimpleNotifications::Delivery.after_delivered = options[:after_delivered] if !!options[:after_delivered]
  SimpleNotifications::Delivery.after_read = options[:after_read] if !!options[:after_read]
  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.



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
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
# File 'lib/simple_notifications/base.rb', line 52

def open_notified_class
  class_eval do
    prepend NotificationActions
    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
    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}

    NotificationActions.module_eval do
      @@actions.each do |action|
        define_method(action) do
          run_callbacks action do
            super()
          end
        end

        define_method("before_#{action}") do
        end

        define_method("after_#{action}") do
          self.notify(sender: @@sender, receivers: @@receivers, message: default_message(self, @@sender, action.to_s))
        end
      end
    end

    @@actions.each do |action|
      define_model_callbacks action
      send("before_#{action}", "before_#{action}".to_sym)
      send("after_#{action}", "after_#{action}".to_sym)
    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: get_obj(options[:sender]), message: default_message(self, get_obj(options[:sender]), 'created'))
      get_obj(options[:receivers]).each {|receiver| notification.deliveries.build(receiver: receiver)}
      notification.save
    end

    # Check if notifications has already been delivered.
    def notified?
      !notifications.blank?
    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

    def default_message(entity, sender, action)
      @message || (method(@@notify_message).call if !!@@notify_message) || "#{get_obj(sender).class.name} #{action} #{entity.class.name} #{entity.name}."
    end

    private

    def get_obj(sender_or_receivers)
      sender_or_receivers.kind_of?(Symbol) ? send(sender_or_receivers) : sender_or_receivers
    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.



41
42
43
44
45
46
47
48
49
# File 'lib/simple_notifications/base.rb', line 41

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.



33
34
35
36
37
38
# File 'lib/simple_notifications/base.rb', line 33

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



183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
# File 'lib/simple_notifications/base.rb', line 183

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



172
173
174
175
176
177
178
179
180
# File 'lib/simple_notifications/base.rb', line 172

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