Module: Stex::Acts::Messagable::InstanceMethods

Defined in:
lib/stex/acts/messagable.rb

Instance Method Summary collapse

Instance Method Details

#messagable_accessor(request) ⇒ Object

Accessor for acts_as_messagable options and helpers

Parameters:

  • request (String, Symbol)

    Requested option or helper, available values are:

    • :sender_name Returns a formatted representation of self which is used in message sender display fields

    • :recipient_name Returns a formatted representation of self which is used in message recipient display fields

    • :forward_to Returns the recipient(s) a message should be forwarded to instead of being delivered to self or nil if not defined (see #acts_as_messagable)

    • :optional_recipients Returns an Array of Array<Symbol, *Messagable, String>, for more details see #acts_as_messagable

    • :store_additional_recipients Returns true|false, depending on the given option in #acts_as_messagable



225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
# File 'lib/stex/acts/messagable.rb', line 225

def messagable_accessor(request)
  @cached_accessors ||= {}
  options           = self.class.acts_as_messagable_options

  @cached_accessors[request.to_sym] ||= case request.to_sym
                                          when :sender_name
                                            Stex::Acts::Messagable.run_method(self, options[:sender_name])
                                          when :recipient_name
                                            Stex::Acts::Messagable.run_method(self, options[:recipient_name])
                                          when :forward_to
                                            Stex::Acts::Messagable.run_method(self, options[:forward_to])
                                          when :optional_recipients
                                            Array(options[:optional_recipients]).map do |identifier, proc, name|
                                              recipient_name = name.is_a?(String) ? name : Stex::Acts::Messagable.run_method(self, name)
                                              [identifier, Stex::Acts::Messagable.run_method(self, proc), recipient_name]
                                            end
                                          when :store_additional_recipients
                                            Stex::Acts::Messagable.run_method(self, options[:store_additional_recipients],
                                                                              options[:store_additional_recipients])
                                          else
                                            raise ArgumentError.new('Invalid Request Argument: ' + request.to_s)
                                        end
end

#send_message(recipients, subject, content, options = {}) ⇒ Object

Sends a message from self to the given list of recipients The whole sending happens in a transaction, so if one message creation fails, none of them are sent.

Examples:

Recipient with optional recipient (see #acts_as_messagable)

my_user.send_message([[my_group, [:tutors]]], 'Subject', 'Body')

Parameters:

  • recipients (Array<Messagable>|Array<Hash>|Messagable)

    The message recipient(s), all have to be messagable The value will be handled as an Array in every case, so if you only have one recipient, you don’t have to put it in brackets. The array elements may either be messagable objects or arrays, mapping messagable to Array<optional recipient identifiers>, see example.

  • subject (String)

    The message message’s subject

  • content (String)

    The message message



270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
# File 'lib/stex/acts/messagable.rb', line 270

def send_message(recipients, subject, content, options = {})
  recipients_with_cause = []
  all_recipients        = []

  #Create a new list of recipients together with the original recipients
  #that caused their existance in this list.
  #Also, determine whether additional recipients should be saved or not
  Array(recipients).each do |recipient_or_array|
    local_recipients = Stex::Acts::Messagable.determine_message_recipients([recipient_or_array])
    recipient        = recipient_or_array.is_a?(Array) ? recipient_or_array.first : recipient_or_array

    all_recipients += local_recipients

    recipients_with_cause << {:cause             => recipient,
                              :store_additionals => recipient.class.acts_as_messagable_options[:store_additional_recipients] && local_recipients.size > 1,
                              :recipients        => local_recipients.uniq}

  end

  all_recipients.uniq!
  processed_recipients = []

  Stex::Acts::Messagable.message_class.transaction do
    recipients_with_cause.each do |recipient_data|
      recipient_data[:recipients].each do |recipient|

        next if processed_recipients.include?(recipient)
        processed_recipients << recipient

        message                       = options.clone
        message[:subject]             = subject
        message[:content]             = content
        message[:original_recipients] = Array(recipients)

        #If the original recipient was set to store additional recipients, we store
        #all recipients that were caused by the same original recipient
        if recipient_data[:store_additionals]
          message[:additional_recipients] = recipient_data[:recipients] - [recipient]
          # If the recipient itself was set to store additional recipients, we store
          # all recipients this message is sent to, regardless of the original recipients
        elsif recipient.class.acts_as_messagable_options[:store_additional_recipients] && final_recipients.size > 1
          message[:additional_recipients] = all_recipients - [recipient]
        end

        #It might happen that a messagable does not actually want to
        #receive messages, but instead do something different.
        if recipient.class.acts_as_messagable_options[:handler]
          recipient.class.acts_as_messagable_options[:handler].call(self, message)
        else
          #Otherwise, a new message is created and sent to the given recipient
          Stex::Acts::Messagable.message_class.create!(message.merge({:sender => self, :recipient => recipient}))
        end
      end
    end

    #Create a copy of the message for the sender
    Stex::Acts::Messagable.message_class.create!(:subject               => subject,
                                                 :content               => content,
                                                 :original_recipients   => Array(recipients),
                                                 :additional_recipients => all_recipients,
                                                 :sender                => self,
                                                 :recipient             => self,
                                                 :sender_copy           => true)
  end
end