message_train 0.6.17 → 0.7.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (80) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +16 -13
  3. data/.rubocop_todo.yml +12 -0
  4. data/.ruby-version +1 -1
  5. data/.travis.yml +1 -1
  6. data/Gemfile +28 -30
  7. data/README.md +284 -0
  8. data/Rakefile +6 -7
  9. data/VERSION +1 -1
  10. data/app/assets/javascripts/ckeditor/{config.js.coffee → config.js} +7 -6
  11. data/app/assets/stylesheets/message_train.scss +0 -8
  12. data/app/controllers/concerns/message_train_authorization.rb +37 -0
  13. data/app/controllers/concerns/message_train_support.rb +41 -69
  14. data/app/controllers/message_train/application_controller.rb +1 -0
  15. data/app/controllers/message_train/boxes_controller.rb +5 -4
  16. data/app/controllers/message_train/conversations_controller.rb +7 -5
  17. data/app/controllers/message_train/messages_controller.rb +43 -27
  18. data/app/controllers/message_train/participants_controller.rb +14 -25
  19. data/app/controllers/message_train/unsubscribes_controller.rb +96 -61
  20. data/app/helpers/message_train/application_helper.rb +13 -7
  21. data/app/helpers/message_train/attachments_helper.rb +4 -12
  22. data/app/helpers/message_train/boxes_helper.rb +4 -14
  23. data/app/helpers/message_train/collectives_helper.rb +23 -29
  24. data/app/helpers/message_train/conversations_helper.rb +52 -30
  25. data/app/helpers/message_train/messages_helper.rb +33 -20
  26. data/app/mailers/message_train/receipt_mailer.rb +22 -12
  27. data/app/models/message_train/attachment.rb +2 -2
  28. data/app/models/message_train/box.rb +182 -228
  29. data/app/models/message_train/conversation.rb +100 -103
  30. data/app/models/message_train/ignore.rb +83 -4
  31. data/app/models/message_train/message.rb +66 -117
  32. data/app/models/message_train/receipt.rb +73 -49
  33. data/app/views/message_train/boxes/show.html.haml +11 -7
  34. data/config/locales/en.yml +1 -0
  35. data/config/routes.rb +6 -12
  36. data/lib/message_train.rb +3 -1
  37. data/lib/message_train/class_methods.rb +51 -0
  38. data/lib/message_train/configuration.rb +28 -3
  39. data/lib/message_train/instance_methods.rb +209 -0
  40. data/lib/message_train/mixin.rb +25 -320
  41. data/message_train.gemspec +83 -83
  42. data/spec/controllers/message_train/boxes_controller_spec.rb +37 -19
  43. data/spec/controllers/message_train/concerns_spec.rb +21 -3
  44. data/spec/controllers/message_train/conversations_controller_spec.rb +41 -18
  45. data/spec/controllers/message_train/messages_controller_spec.rb +112 -31
  46. data/spec/controllers/message_train/participants_controller_spec.rb +33 -7
  47. data/spec/controllers/message_train/unsubscribes_controller_spec.rb +10 -8
  48. data/spec/dummy/app/assets/stylesheets/{application.css.scss → application.scss} +2 -1
  49. data/spec/dummy/app/assets/stylesheets/bootstrap-everything.scss +54 -0
  50. data/spec/dummy/app/models/group.rb +1 -1
  51. data/spec/dummy/app/views/layouts/application.html.haml +9 -8
  52. data/spec/dummy/bin/setup +8 -8
  53. data/spec/dummy/config/application.rb +0 -3
  54. data/spec/dummy/config/environments/test.rb +4 -2
  55. data/spec/dummy/db/schema.rb +94 -103
  56. data/spec/dummy/db/test.sqlite3 +0 -0
  57. data/spec/factories/attachment.rb +3 -1
  58. data/spec/factories/message.rb +2 -3
  59. data/spec/features/boxes_spec.rb +0 -3
  60. data/spec/helpers/message_train/application_helper_spec.rb +3 -2
  61. data/spec/helpers/message_train/attachment_helper_spec.rb +4 -0
  62. data/spec/helpers/message_train/boxes_helper_spec.rb +1 -0
  63. data/spec/helpers/message_train/collectives_helper_spec.rb +1 -0
  64. data/spec/helpers/message_train/conversations_helper_spec.rb +3 -2
  65. data/spec/helpers/message_train/messages_helper_spec.rb +2 -1
  66. data/spec/models/group_spec.rb +6 -4
  67. data/spec/models/message_train/box_spec.rb +0 -88
  68. data/spec/models/message_train/ignore_spec.rb +65 -0
  69. data/spec/models/message_train/message_spec.rb +6 -5
  70. data/spec/models/message_train/receipt_spec.rb +6 -8
  71. data/spec/models/role_spec.rb +2 -2
  72. data/spec/models/user_spec.rb +29 -101
  73. data/spec/rails_helper.rb +16 -30
  74. data/spec/support/feature_behaviors.rb +2 -1
  75. data/spec/support/shared_connection.rb +5 -0
  76. data/spec/support/utilities.rb +7 -8
  77. metadata +145 -120
  78. data/README.rdoc +0 -175
  79. data/spec/dummy/app/models/.keep +0 -0
  80. data/spec/dummy/log/.keep +0 -0
@@ -3,29 +3,66 @@ module MessageTrain
3
3
  class Receipt < ActiveRecord::Base
4
4
  belongs_to :recipient, polymorphic: true
5
5
  belongs_to :received_through, polymorphic: true
6
- belongs_to(
7
- :message,
8
- foreign_key: :message_train_message_id,
9
- touch: true
10
- )
6
+ belongs_to :message, foreign_key: :message_train_message_id, touch: true
7
+ delegate :conversation, to: :message
11
8
  validates_presence_of :recipient, :message
12
9
 
13
- default_scope { order(updated_at: :desc) }
10
+ after_create :notify
11
+
14
12
  scope :sender_receipt, -> { where(sender: true) }
15
13
  scope :recipient_receipt, -> { where(sender: false) }
14
+ scope :for, ->(recipient) { where(recipient: recipient) }
16
15
  scope :by, ->(sender) { sender_receipt.for(sender) }
17
- scope :for, (lambda do |recipient|
18
- where(recipient: recipient)
19
- end)
20
16
  scope :to, ->(recipient) { recipient_receipt.for(recipient) }
21
- scope :through, (lambda do |received_through|
22
- where(received_through: received_through)
23
- end)
17
+ scope :through, ->(recipient) { where(received_through: recipient) }
24
18
  scope :trashed, ->(setting = true) { where(marked_trash: setting) }
25
19
  scope :read, ->(setting = true) { where(marked_read: setting) }
26
20
  scope :deleted, ->(setting = true) { where(marked_deleted: setting) }
21
+ scope :for_messages, ->(messages) { where(message: messages) }
22
+ scope :flagged, ->(flag, *args) { send(flag.to_sym, *args) }
27
23
 
28
- after_create :notify
24
+ def self.message_ids
25
+ pluck(:message_train_message_id)
26
+ end
27
+
28
+ def self.messages
29
+ MessageTrain::Message.where(id: message_ids)
30
+ end
31
+
32
+ def self.conversation_ids
33
+ messages.conversation_ids
34
+ end
35
+
36
+ def self.conversations
37
+ MessageTrain::Conversation.where(id: conversation_ids)
38
+ end
39
+
40
+ def self.generate_for_sender(sender)
41
+ first_or_create!(recipient: sender, received_through: sender, sender: 1)
42
+ end
43
+
44
+ def self.send_to_or_through(recipient)
45
+ if recipient.class.collective?
46
+ send_through recipient, recipient.class.valid_recipients_method
47
+ else
48
+ send_to recipient
49
+ end
50
+ end
51
+
52
+ def self.send_to(recipient)
53
+ receipt = new recipient: recipient, received_through: recipient
54
+ return if receipt.conversation.participant_ignored?(recipient)
55
+ receipt.save
56
+ end
57
+
58
+ def self.send_through(recipient, end_recipient_method)
59
+ recipient.send(end_recipient_method).distinct.each do |end_recipient|
60
+ receipt = new recipient: end_recipient, received_through: recipient
61
+ next if receipt.conversation.participant_ignored?(end_recipient) ||
62
+ receipt.message.sender == end_recipient
63
+ receipt.save
64
+ end
65
+ end
29
66
 
30
67
  def mark(mark_to_set)
31
68
  if mark_to_set.to_s =~ /^un/
@@ -39,47 +76,35 @@ module MessageTrain
39
76
  update_attribute(column, setting)
40
77
  end
41
78
 
42
- def self.message_ids
43
- pluck(:message_train_message_id)
44
- end
45
-
46
- def self.messages
47
- MessageTrain::Message.joins(:receipts)
48
- .where(message_train_receipts: { id: where(nil) })
79
+ def self.mark(mark_to_set)
80
+ where(nil).each { |receipt| receipt.mark(mark_to_set) }
49
81
  end
50
82
 
51
- def self.conversation_ids
52
- messages.conversation_ids
83
+ def self.method_missing(method_sym, *args, &block)
84
+ method_string = method_sym.to_s
85
+ if method_string =~ /\A(.*)_(by|to|for|through)\z/
86
+ first_sym = Regexp.last_match[1].to_sym
87
+ second_sym = Regexp.last_match[2].to_sym
88
+ return run_prepositional_method(first_sym, second_sym, *args)
89
+ elsif method_string =~ /\Aun(.*)\z/
90
+ first_sym = Regexp.last_match[1].to_sym
91
+ return run_un_method(first_sym)
92
+ end
93
+ super
53
94
  end
54
95
 
55
- def self.conversations
56
- MessageTrain::Conversation.joins(:receipts)
57
- .where(
58
- message_train_receipts: { id: where(nil) }
59
- )
96
+ def self.run_prepositional_method(first_sym, second_sym, *args)
97
+ return send(second_sym, *args) if first_sym == :receipts
98
+ send(first_sym).send(second_sym, *args)
60
99
  end
61
100
 
62
- def self.method_missing(method_sym, *arguments, &block)
63
- # the first argument is a Symbol, so you need to_s it if you want to
64
- # pattern match
65
- if method_sym.to_s =~ /^receipts_(by|to|for|through)$/
66
- send(Regexp.last_match[1].to_sym, arguments.first)
67
- elsif method_sym.to_s =~ /^(.*)_(by|to|for|through)$/
68
- send(Regexp.last_match[1].to_sym)
69
- .send(Regexp.last_match[2].to_sym, arguments.first)
70
- elsif method_sym.to_s =~ /^un(.*)$/
71
- send(Regexp.last_match[1].to_sym, false)
72
- else
73
- super
74
- end
101
+ def self.run_un_method(first_sym)
102
+ send(first_sym, false)
75
103
  end
76
104
 
77
- # It's important to know Object defines respond_to to take two parameters:
78
- # the method to check, and whether to include private methods
79
- # http://www.ruby-doc.org/core/classes/Object.html#M000333
80
- def self.respond_to?(method_sym, include_private = false)
81
- if method_sym.to_s =~ /^(.*)_(by|to|for|through)$/ ||
82
- method_sym.to_s =~ /^un(.*)$/
105
+ def self.respond_to_missing?(method_sym, include_private = false)
106
+ if method_sym.to_s =~ /\A(.*)_(by|to|for|through)\z/ ||
107
+ method_sym.to_s =~ /\Aun(.*)\z/
83
108
  true
84
109
  else
85
110
  super
@@ -89,9 +114,8 @@ module MessageTrain
89
114
  private
90
115
 
91
116
  def notify
92
- unless sender? || recipient.unsubscribed_from?(received_through)
93
- ReceiptMailer.notification_email(self).deliver_later
94
- end
117
+ return if sender? || recipient.unsubscribed_from?(received_through)
118
+ ReceiptMailer.notification_email(self).deliver_now
95
119
  end
96
120
  end
97
121
  end
@@ -1,12 +1,16 @@
1
- - if @collective.nil?
2
- - add_title @box.title
3
- - marking_path = message_train.box_path(@box.division)
4
- - else
5
- - add_title collective_name(@collective) + ' ' + @box.title
6
- - marking_path = message_train.collective_box_path(@collective.path_part, @box.division)
1
+ :ruby
2
+ if @collective.nil?
3
+ add_title @box.title
4
+ marking_path = message_train.box_path(@box.division)
5
+ else
6
+ add_title collective_name(@collective) + ' ' + @box.title
7
+ marking_path = message_train.collective_box_path(@collective.path_part, @box.division)
8
+ end
7
9
  - cache ['message-train', 'boxes-show', @box_user, @box] do
8
10
  = form_tag marking_path, method: :put, remote: true, id: 'box', data: { type: :json } do
9
- - unless @conversations.empty?
11
+ - if @conversations.empty?
12
+ %em= :box_is_empty.l
13
+ - else
10
14
  #box-actions.box-actions
11
15
  .btn-group.check-all
12
16
  %button.btn.btn-default{ type: 'button' }
@@ -22,6 +22,7 @@ en:
22
22
  at_time_through_received_a_message: "At %{time}, %{through} received a message: <a href=\"%{path}\">%{subject}</a>"
23
23
  attachment_preview: 'Attachment Preview'
24
24
  attachments: 'Attachments'
25
+ box_is_empty: 'This box is empty.'
25
26
  box_title_in: 'Inbox'
26
27
  box_title_sent: 'Sent'
27
28
  box_title_all: 'All'
data/config/routes.rb CHANGED
@@ -30,26 +30,20 @@ MessageTrain::Engine.routes.draw do
30
30
  end
31
31
 
32
32
  match(
33
- '/box(/*path)' => redirect do |_p, req|
34
- req.flash[:error] = :you_must_sign_in_or_sign_up_to_continue.l
35
- MessageTrain.configuration.user_sign_in_path
36
- end,
33
+ '/box(/*path)',
34
+ to: 'boxes#redirect_to_sign_in',
37
35
  via: [:get, :put, :post, :delete]
38
36
  )
39
37
 
40
38
  match(
41
- '/collectives(/*path)' => redirect do |_p, req|
42
- req.flash[:error] = :you_must_sign_in_or_sign_up_to_continue.l
43
- MessageTrain.configuration.user_sign_in_path
44
- end,
39
+ '/collectives(/*path)',
40
+ to: 'boxes#redirect_to_sign_in',
45
41
  via: [:get, :put, :post, :delete]
46
42
  )
47
43
 
48
44
  match(
49
- '/unsubscribes(/*path)' => redirect do |_p, req|
50
- req.flash[:error] = :you_must_sign_in_or_sign_up_to_continue.l
51
- MessageTrain.configuration.user_sign_in_path
52
- end,
45
+ '/unsubscribes(/*path)',
46
+ to: 'unsubscribes#redirect_to_sign_in',
53
47
  via: [:get, :put, :post, :delete]
54
48
  )
55
49
  end
data/lib/message_train.rb CHANGED
@@ -13,9 +13,11 @@ module MessageTrain
13
13
  require 'message_train/localization'
14
14
  require 'message_train/version'
15
15
  require 'message_train/mixin'
16
+ require 'message_train/class_methods'
17
+ require 'message_train/instance_methods'
16
18
 
17
19
  require 'haml-rails'
18
20
  require 'bootstrap_leather'
19
21
  end
20
22
 
21
- ActiveRecord::Base.send(:include, MessageTrain::Mixin)
23
+ ActiveRecord::Base.send(:extend, MessageTrain::Mixin)
@@ -0,0 +1,51 @@
1
+ module MessageTrain
2
+ # Extended when message_train mixin is run
3
+ module ClassMethods
4
+ def message_train_address_book(for_participant)
5
+ method = MessageTrain.configuration.address_book_methods[
6
+ message_train_table_sym
7
+ ]
8
+ method ||= MessageTrain.configuration.address_book_method
9
+ if method.present? && respond_to?(method)
10
+ send(method, for_participant)
11
+ else
12
+ all
13
+ end
14
+ end
15
+
16
+ def find_by_message_train_slug(slug)
17
+ find_by(slug_column => slug.strip)
18
+ end
19
+
20
+ def where_slug_starts_with(string)
21
+ return where(nil) unless string.present?
22
+ pattern = Regexp.union('\\', '%', '_')
23
+ string = string.gsub(pattern) { |x| ['\\', x].join }
24
+ where("#{slug_column} LIKE ?", "#{string}%")
25
+ end
26
+
27
+ def slug_column
28
+ MessageTrain.configuration.slug_columns[message_train_table_sym] || :slug
29
+ end
30
+
31
+ def name_column
32
+ MessageTrain.configuration.name_columns[message_train_table_sym] || :name
33
+ end
34
+
35
+ def valid_senders_method
36
+ MessageTrain.configuration
37
+ .valid_senders_methods[message_train_table_sym] ||
38
+ :self_collection
39
+ end
40
+
41
+ def valid_recipients_method
42
+ MessageTrain.configuration
43
+ .valid_recipients_methods[message_train_table_sym] ||
44
+ :self_collection
45
+ end
46
+
47
+ def collective?
48
+ valid_senders_method != :self_collection
49
+ end
50
+ end
51
+ end
@@ -1,12 +1,34 @@
1
1
  # MessageTrain module
2
2
  module MessageTrain
3
+ # @conversions[:mixin_option] = :configuration_name
4
+ @conversions = {}
5
+ @conversions[:slug_column] = :slug_columns
6
+ @conversions[:name_column] = :name_columns
7
+ @conversions[:collectives_for_recipient] = :collectives_for_recipient_methods
8
+ @conversions[:valid_recipients] = :valid_recipients_methods
9
+ @conversions[:valid_senders] = :valid_senders_methods
10
+ @conversions[:address_book_method] = :address_book_methods
11
+
3
12
  def self.configure(configuration = MessageTrain::Configuration.new)
4
- block_given? && yield(configuration)
5
- @@configuration = configuration
13
+ yield(configuration) if block_given?
14
+ @configuration = configuration
6
15
  end
7
16
 
8
17
  def self.configuration
9
- @@configuration ||= MessageTrain::Configuration.new
18
+ @configuration ||= MessageTrain::Configuration.new
19
+ end
20
+
21
+ def self.configure_table(table_sym, name, options)
22
+ configure(@configuration) do |config|
23
+ config.recipient_tables[table_sym] = name
24
+ @conversions.each do |mixin_option_sym, configuration_name_sym|
25
+ value = options[mixin_option_sym]
26
+ next unless value.present?
27
+ setting = config.send(configuration_name_sym)
28
+ setting[table_sym] = value
29
+ config.send("#{configuration_name_sym}=", setting)
30
+ end
31
+ end
10
32
  end
11
33
 
12
34
  # MessageTrain configuration
@@ -26,6 +48,8 @@ module MessageTrain
26
48
  :from_email,
27
49
  :site_name
28
50
 
51
+ # rubocop:disable Metrics/MethodLength
52
+ # Don't see any way to shorten this
29
53
  def initialize
30
54
  self.recipient_tables = {}
31
55
  self.slug_columns = { users: :slug }
@@ -42,5 +66,6 @@ module MessageTrain
42
66
  self.from_email = ''
43
67
  self.site_name = 'Example Site Name'
44
68
  end
69
+ # rubocop:enable Metrics/MethodLength
45
70
  end
46
71
  end
@@ -0,0 +1,209 @@
1
+ module MessageTrain
2
+ # Included in method when message_train mixin is run
3
+ module InstanceMethods
4
+ def self.included(base)
5
+ base.send :include, InstanceMethods::GeneralMethods
6
+ base.message_train_relationships.include?(:recipient) &&
7
+ base.send(:include, InstanceMethods::RecipientMethods)
8
+ end
9
+
10
+ # Included by InstanceMethods when message_train mixin is run
11
+ module GeneralMethods
12
+ BOX_DEFINITIONS = {
13
+ in: :with_untrashed_to,
14
+ sent: :with_untrashed_by,
15
+ all: :with_untrashed_for,
16
+ drafts: :with_drafts_by,
17
+ trash: :with_trashed_for,
18
+ ignored: :ignored
19
+ }.freeze
20
+
21
+ BOX_OMISSION_DEFINITIONS = {
22
+ trash: :without_trashed_for,
23
+ drafts: :with_ready_for,
24
+ ignored: :unignored
25
+ }.freeze
26
+
27
+ def path_part
28
+ return unless self.class.collective?
29
+ # This must mean it's a collective
30
+ "#{self.class.table_name}:#{message_train_slug}"
31
+ end
32
+
33
+ def valid_senders
34
+ send(self.class.valid_senders_method)
35
+ end
36
+
37
+ def allows_sending_by?(sender)
38
+ valid_senders.include? sender
39
+ end
40
+
41
+ def valid_recipients
42
+ send(self.class.valid_recipients_method)
43
+ end
44
+
45
+ def allows_access_by?(recipient)
46
+ allows_receiving_by?(recipient) || allows_sending_by?(recipient)
47
+ end
48
+
49
+ def allows_receiving_by?(recipient)
50
+ return false if valid_recipients.empty?
51
+ valid_recipients.include? recipient
52
+ end
53
+
54
+ def self_collection
55
+ # This turns a single record into an active record collection.
56
+ self.class.where(id: id)
57
+ end
58
+
59
+ def conversations(*args)
60
+ division = args[0] || :in
61
+ participant = args[1] || self
62
+ definition_method = BOX_DEFINITIONS[division]
63
+ return if definition_method.nil?
64
+ conversations = defined_conversations(definition_method, participant)
65
+ BOX_OMISSION_DEFINITIONS.each do |division_key, omission_method|
66
+ next if division_key == division # Because not to be omitted
67
+ conversations = conversations.send(omission_method, participant)
68
+ end
69
+ conversations
70
+ end
71
+
72
+ def defined_conversations(definition, participant)
73
+ MessageTrain::Conversation.with_messages_through(self)
74
+ .without_deleted_for(participant)
75
+ .send(definition, participant)
76
+ end
77
+
78
+ def boxes_for_participant(participant)
79
+ original_order = [:in, :sent, :all, :drafts, :trash, :ignored]
80
+ divisions = [:all, :trash]
81
+ if respond_to?(:messages) || allows_sending_by?(participant)
82
+ divisions += [:sent, :drafts]
83
+ end
84
+ divisions += [:in, :ignored] if allows_receiving_by?(participant)
85
+ divisions.sort_by! { |x| original_order.index x }
86
+ divisions.collect { |d| MessageTrain::Box.new(self, d, participant) }
87
+ end
88
+
89
+ def all_conversations(*args)
90
+ participant = args[0] || self
91
+ results = MessageTrain::Conversation.with_messages_through(self)
92
+ return [] if results.empty?
93
+ results.with_messages_for(participant)
94
+ end
95
+
96
+ def all_messages(*args)
97
+ participant = args[0] || self
98
+ results = MessageTrain::Message.with_receipts_through(self)
99
+ return [] if results.empty?
100
+ results.with_receipts_for(participant)
101
+ end
102
+
103
+ def unsubscribed_from_all?
104
+ unsubscribes.where(from: nil).exists?
105
+ end
106
+
107
+ def unsubscribed_from?(from)
108
+ unsubscribed_from_all? || unsubscribes.where(from: from).exists?
109
+ end
110
+
111
+ def unsubscribe_from(from)
112
+ unsubscribes.find_or_create_by(from: from)
113
+ end
114
+
115
+ def subscriptions
116
+ subscriptions = [self_subscription]
117
+ subscriptions += collective_boxes.values.map do |boxes|
118
+ boxes.map { |box| subscription(box) }
119
+ end
120
+ subscriptions.flatten.compact
121
+ end
122
+ end
123
+
124
+ # Included by InstanceMethods when message_train mixin is run, if this is a
125
+ # recipient
126
+ module RecipientMethods
127
+ def box(*args)
128
+ division = args[0] || :in
129
+ participant = args[1] || self
130
+ @box ||= MessageTrain::Box.new(self, division, participant)
131
+ end
132
+
133
+ def collective_boxes(*args)
134
+ division = args[0] || :in
135
+ participant = args[1] || self
136
+ cb_tables = MessageTrain.configuration
137
+ .collectives_for_recipient_methods
138
+ return {} if cb_tables.empty?
139
+ Hash[cb_tables.map do |key, value|
140
+ box = table_collective_box(key, value, division, participant)
141
+ [key, box]
142
+ end]
143
+ end
144
+
145
+ def collective_boxes_unread_counts
146
+ Hash[collective_boxes.map do |key, collectives|
147
+ [key, collectives.collect(&:unread_count).sum]
148
+ end]
149
+ end
150
+
151
+ def collective_boxes_show_flags
152
+ Hash[collective_boxes.map do |key, collectives|
153
+ flag = collectives.select do |collective_box|
154
+ collective_box.parent.allows_access_by?(self)
155
+ end.any?
156
+ [key, flag]
157
+ end]
158
+ end
159
+
160
+ def table_collective_box(
161
+ table_sym, collectives_method, division, participant
162
+ )
163
+ model = MessageTrain.configuration
164
+ .recipient_tables[table_sym]
165
+ .constantize
166
+ collectives = model.send(collectives_method, participant)
167
+ collectives.map { |x| x.box(division, participant) }.compact
168
+ end
169
+
170
+ def all_boxes(*args)
171
+ participant = args[0] || self
172
+ divisions = [:in, :sent, :all, :drafts, :trash, :ignored]
173
+ divisions.collect do |division|
174
+ MessageTrain::Box.new(self, division, participant)
175
+ end
176
+ end
177
+
178
+ def message_train_name
179
+ send(self.class.name_column)
180
+ end
181
+
182
+ def message_train_slug
183
+ send(self.class.slug_column)
184
+ end
185
+
186
+ protected
187
+
188
+ def self_subscription
189
+ {
190
+ from: self, from_type: self.class.name, from_id: id,
191
+ from_name: :messages_directly_to_myself.l,
192
+ unsubscribe: unsubscribes.find_by(from: self)
193
+ }
194
+ end
195
+
196
+ def subscription(box)
197
+ parent = box.parent
198
+ return unless parent.allows_receiving_by?(self)
199
+ {
200
+ from: parent, from_type: parent.class.name, from_id: parent.id,
201
+ from_name: :messages_to_collective.l(
202
+ collective: parent.message_train_name
203
+ ),
204
+ unsubscribe: unsubscribes.find_by(from: parent)
205
+ }
206
+ end
207
+ end
208
+ end
209
+ end