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.
- checksums.yaml +4 -4
- data/.rubocop.yml +16 -13
- data/.rubocop_todo.yml +12 -0
- data/.ruby-version +1 -1
- data/.travis.yml +1 -1
- data/Gemfile +28 -30
- data/README.md +284 -0
- data/Rakefile +6 -7
- data/VERSION +1 -1
- data/app/assets/javascripts/ckeditor/{config.js.coffee → config.js} +7 -6
- data/app/assets/stylesheets/message_train.scss +0 -8
- data/app/controllers/concerns/message_train_authorization.rb +37 -0
- data/app/controllers/concerns/message_train_support.rb +41 -69
- data/app/controllers/message_train/application_controller.rb +1 -0
- data/app/controllers/message_train/boxes_controller.rb +5 -4
- data/app/controllers/message_train/conversations_controller.rb +7 -5
- data/app/controllers/message_train/messages_controller.rb +43 -27
- data/app/controllers/message_train/participants_controller.rb +14 -25
- data/app/controllers/message_train/unsubscribes_controller.rb +96 -61
- data/app/helpers/message_train/application_helper.rb +13 -7
- data/app/helpers/message_train/attachments_helper.rb +4 -12
- data/app/helpers/message_train/boxes_helper.rb +4 -14
- data/app/helpers/message_train/collectives_helper.rb +23 -29
- data/app/helpers/message_train/conversations_helper.rb +52 -30
- data/app/helpers/message_train/messages_helper.rb +33 -20
- data/app/mailers/message_train/receipt_mailer.rb +22 -12
- data/app/models/message_train/attachment.rb +2 -2
- data/app/models/message_train/box.rb +182 -228
- data/app/models/message_train/conversation.rb +100 -103
- data/app/models/message_train/ignore.rb +83 -4
- data/app/models/message_train/message.rb +66 -117
- data/app/models/message_train/receipt.rb +73 -49
- data/app/views/message_train/boxes/show.html.haml +11 -7
- data/config/locales/en.yml +1 -0
- data/config/routes.rb +6 -12
- data/lib/message_train.rb +3 -1
- data/lib/message_train/class_methods.rb +51 -0
- data/lib/message_train/configuration.rb +28 -3
- data/lib/message_train/instance_methods.rb +209 -0
- data/lib/message_train/mixin.rb +25 -320
- data/message_train.gemspec +83 -83
- data/spec/controllers/message_train/boxes_controller_spec.rb +37 -19
- data/spec/controllers/message_train/concerns_spec.rb +21 -3
- data/spec/controllers/message_train/conversations_controller_spec.rb +41 -18
- data/spec/controllers/message_train/messages_controller_spec.rb +112 -31
- data/spec/controllers/message_train/participants_controller_spec.rb +33 -7
- data/spec/controllers/message_train/unsubscribes_controller_spec.rb +10 -8
- data/spec/dummy/app/assets/stylesheets/{application.css.scss → application.scss} +2 -1
- data/spec/dummy/app/assets/stylesheets/bootstrap-everything.scss +54 -0
- data/spec/dummy/app/models/group.rb +1 -1
- data/spec/dummy/app/views/layouts/application.html.haml +9 -8
- data/spec/dummy/bin/setup +8 -8
- data/spec/dummy/config/application.rb +0 -3
- data/spec/dummy/config/environments/test.rb +4 -2
- data/spec/dummy/db/schema.rb +94 -103
- data/spec/dummy/db/test.sqlite3 +0 -0
- data/spec/factories/attachment.rb +3 -1
- data/spec/factories/message.rb +2 -3
- data/spec/features/boxes_spec.rb +0 -3
- data/spec/helpers/message_train/application_helper_spec.rb +3 -2
- data/spec/helpers/message_train/attachment_helper_spec.rb +4 -0
- data/spec/helpers/message_train/boxes_helper_spec.rb +1 -0
- data/spec/helpers/message_train/collectives_helper_spec.rb +1 -0
- data/spec/helpers/message_train/conversations_helper_spec.rb +3 -2
- data/spec/helpers/message_train/messages_helper_spec.rb +2 -1
- data/spec/models/group_spec.rb +6 -4
- data/spec/models/message_train/box_spec.rb +0 -88
- data/spec/models/message_train/ignore_spec.rb +65 -0
- data/spec/models/message_train/message_spec.rb +6 -5
- data/spec/models/message_train/receipt_spec.rb +6 -8
- data/spec/models/role_spec.rb +2 -2
- data/spec/models/user_spec.rb +29 -101
- data/spec/rails_helper.rb +16 -30
- data/spec/support/feature_behaviors.rb +2 -1
- data/spec/support/shared_connection.rb +5 -0
- data/spec/support/utilities.rb +7 -8
- metadata +145 -120
- data/README.rdoc +0 -175
- data/spec/dummy/app/models/.keep +0 -0
- data/spec/dummy/log/.keep +0 -0
@@ -7,61 +7,90 @@ module MessageTrain
|
|
7
7
|
has_many :attachments, through: :messages
|
8
8
|
|
9
9
|
# Scopes
|
10
|
-
|
10
|
+
scope :by_ignored, ->(p, flag) { flag ? ignored(p) : unignored(p) }
|
11
|
+
|
11
12
|
scope :ignored, ->(participant) { where(id: ignored_ids_for(participant)) }
|
13
|
+
|
12
14
|
scope :unignored, (lambda do |participant|
|
13
15
|
where.not(id: ignored_ids_for(participant))
|
14
16
|
end)
|
17
|
+
|
15
18
|
scope :with_drafts_by, (lambda do |participant|
|
16
|
-
|
17
|
-
message_train_messages: {
|
18
|
-
id: messages.drafts.with_receipts_by(participant)
|
19
|
-
}
|
20
|
-
)
|
19
|
+
messages.drafts.with_receipts_by(participant).conversations
|
21
20
|
end)
|
21
|
+
|
22
22
|
scope :with_ready_for, (lambda do |participant|
|
23
|
-
|
24
|
-
message_train_messages: {
|
25
|
-
id: messages.ready.with_receipts_for(participant)
|
26
|
-
}
|
27
|
-
)
|
23
|
+
messages.ready.with_receipts_for(participant).conversations
|
28
24
|
end)
|
25
|
+
|
29
26
|
scope :with_messages_for, (lambda do |participant|
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
)
|
27
|
+
messages.with_receipts_for(participant).conversations
|
28
|
+
end)
|
29
|
+
|
30
|
+
scope :without_trashed_for, (lambda do |participant|
|
31
|
+
where.not(id: messages.with_trashed_for(participant).conversations)
|
35
32
|
end)
|
33
|
+
|
34
|
+
scope :without_deleted_for, (lambda do |participant|
|
35
|
+
where.not(id: messages.with_deleted_for(participant).conversations)
|
36
|
+
end)
|
37
|
+
|
36
38
|
scope :with_messages_through, (lambda do |participant|
|
37
|
-
|
38
|
-
message_train_messages: {
|
39
|
-
id: messages.with_receipts_through(participant)
|
40
|
-
}
|
41
|
-
)
|
39
|
+
messages.with_receipts_through(participant).conversations
|
42
40
|
end)
|
43
41
|
|
44
42
|
scope :filter_by_receipt_method, (lambda do |receipt_method, participant|
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
43
|
+
messages.receipts.send(receipt_method, participant).conversations
|
44
|
+
end)
|
45
|
+
|
46
|
+
scope :filter_by_division, (lambda do |division|
|
47
|
+
found = if division == :drafts
|
48
|
+
with_drafts_by(participant)
|
49
|
+
else
|
50
|
+
with_ready_for(participant)
|
51
|
+
end
|
52
|
+
found.by_ignored(participant, division == :ignored)
|
49
53
|
end)
|
50
54
|
|
51
|
-
scope :
|
55
|
+
scope :filter_by_preposition, (lambda do |prep, *args|
|
56
|
+
messages.filter_by_receipt_method(prep, *args).conversations
|
57
|
+
end)
|
58
|
+
|
59
|
+
scope :filter_by_status_and_preposition, (lambda do |status, prep, *args|
|
60
|
+
case status
|
61
|
+
when :ready, :drafts
|
62
|
+
messages.send(status)
|
63
|
+
.filter_by_receipt_method(prep, *args)
|
64
|
+
.conversations
|
65
|
+
when :messages
|
66
|
+
filter_by_preposition(prep, *args)
|
67
|
+
else
|
68
|
+
filter_by_receipt_method("#{status}_#{prep}", *args)
|
69
|
+
end
|
70
|
+
end)
|
71
|
+
|
72
|
+
def self.ignored_ids_for(participant)
|
52
73
|
MessageTrain::Ignore.find_all_by_participant(participant)
|
53
74
|
.pluck(:message_train_conversation_id)
|
54
|
-
end
|
75
|
+
end
|
76
|
+
|
77
|
+
def self.messages
|
78
|
+
MessageTrain::Message.for_conversations(ids)
|
79
|
+
end
|
55
80
|
|
56
81
|
def default_recipients_for(sender)
|
57
|
-
default_recipients =
|
58
|
-
|
59
|
-
|
60
|
-
default_recipients << receipt.recipient
|
61
|
-
end
|
62
|
-
end
|
82
|
+
default_recipients = messages.with_receipts_for(sender).map do |c|
|
83
|
+
c.receipts.map(&:recipient)
|
84
|
+
end.flatten.uniq
|
63
85
|
default_recipients.delete(sender)
|
64
|
-
default_recipients
|
86
|
+
default_recipients
|
87
|
+
end
|
88
|
+
|
89
|
+
def new_reply(args)
|
90
|
+
args[:reply_recipients] = default_recipients_for(args.delete(:box).parent)
|
91
|
+
args[:subject] = "Re: #{subject}"
|
92
|
+
args[:body] = "<blockquote>#{messages.last.body}</blockquote><p></p>"
|
93
|
+
messages.build(args)
|
65
94
|
end
|
66
95
|
|
67
96
|
def participant_ignore(participant)
|
@@ -73,88 +102,56 @@ module MessageTrain
|
|
73
102
|
end
|
74
103
|
|
75
104
|
def participant_ignored?(participant)
|
76
|
-
|
77
|
-
false
|
78
|
-
else
|
79
|
-
!ignores.find_all_by_participant(participant).empty?
|
80
|
-
end
|
105
|
+
ignores.empty? ? false : ignores.find_all_by_participant(participant).any?
|
81
106
|
end
|
82
107
|
|
83
108
|
def mark(mark, participant)
|
84
109
|
messages.mark(mark, participant)
|
85
110
|
end
|
86
111
|
|
87
|
-
def
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
# pattern match
|
94
|
-
if method_sym.to_s =~ /^includes_((.*)_(by|to|for|through))\?$/
|
95
|
-
case Regexp.last_match[2]
|
96
|
-
when 'ready', 'drafts'
|
97
|
-
if Regexp.last_match[3] == 'by'
|
98
|
-
messages.send(Regexp.last_match[2]).by(arguments.first).any?
|
99
|
-
else
|
100
|
-
messages.send(Regexp.last_match[2]).receipts.send(
|
101
|
-
"receipts_#{Regexp.last_match[3]}".to_sym,
|
102
|
-
arguments.first
|
103
|
-
).any?
|
104
|
-
end
|
105
|
-
else
|
106
|
-
receipts.send(Regexp.last_match[1].to_sym, arguments.first).any?
|
107
|
-
end
|
108
|
-
else
|
109
|
-
super
|
110
|
-
end
|
112
|
+
def method_missing(method_sym, *args, &block)
|
113
|
+
string = method_sym.to_s
|
114
|
+
return super unless string =~ /\Aincludes_(.*)_(by|to|for|through)\?\z/
|
115
|
+
includes_matches_with_preposition?(
|
116
|
+
Regexp.last_match[1].to_sym, Regexp.last_match[2].to_sym, *args
|
117
|
+
)
|
111
118
|
end
|
112
119
|
|
113
|
-
def
|
114
|
-
|
115
|
-
|
116
|
-
if method_sym.to_s =~ /^with_((.*)_(by|to|for|through))$/
|
117
|
-
case Regexp.last_match[2]
|
118
|
-
when 'ready', 'drafts'
|
119
|
-
messages.send(
|
120
|
-
Regexp.last_match[2]
|
121
|
-
).filter_by_receipt_method(
|
122
|
-
"receipts_#{Regexp.last_match[3]}".to_sym,
|
123
|
-
arguments.first
|
124
|
-
).conversations
|
125
|
-
when 'messages'
|
126
|
-
messages.filter_by_receipt_method(
|
127
|
-
"receipts_#{Regexp.last_match[3]}".to_sym,
|
128
|
-
arguments.first
|
129
|
-
).conversations
|
130
|
-
else
|
131
|
-
filter_by_receipt_method(
|
132
|
-
Regexp.last_match[1].to_sym,
|
133
|
-
arguments.first
|
134
|
-
)
|
135
|
-
end
|
136
|
-
else
|
137
|
-
super
|
120
|
+
def includes_matches_with_preposition?(flag, prep, *args)
|
121
|
+
unless [:ready, :drafts].include? flag
|
122
|
+
return includes_matching_receipts?("#{flag}_#{prep}".to_sym, *args)
|
138
123
|
end
|
124
|
+
return includes_matching_messages_by?(flag, *args) if prep == 'by'
|
125
|
+
includes_matching_messages_with_prep?(flag, prep, *args)
|
139
126
|
end
|
140
127
|
|
141
|
-
|
142
|
-
|
143
|
-
# http://www.ruby-doc.org/core/classes/Object.html#M000333
|
144
|
-
def respond_to?(method_sym, include_private = false)
|
145
|
-
if method_sym.to_s =~ /^includes_((.*)_(by|to|for|through))\?$/
|
146
|
-
true
|
147
|
-
else
|
148
|
-
super
|
149
|
-
end
|
128
|
+
def includes_matching_receipts?(match_method_sym, *args)
|
129
|
+
receipts.send(match_method_sym, *args).any?
|
150
130
|
end
|
151
131
|
|
152
|
-
def
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
132
|
+
def respond_to_missing?(method_sym, include_private = false)
|
133
|
+
method_sym.to_s =~ /\Aincludes_.*_(by|to|for|through)\?\z/ || super
|
134
|
+
end
|
135
|
+
|
136
|
+
def self.method_missing(method_sym, *args, &block)
|
137
|
+
return super unless method_sym.to_s =~ /^with_(.*)_(by|to|for|through)$/
|
138
|
+
status = Regexp.last_match[1].to_sym
|
139
|
+
preposition = Regexp.last_match[2].to_sym
|
140
|
+
filter_by_status_and_preposition(status, preposition, *args)
|
141
|
+
end
|
142
|
+
|
143
|
+
def self.respond_to_missing?(method_sym, include_private = false)
|
144
|
+
method_sym.to_s =~ /^with_(.*)_(by|to|for|through)$/ || super
|
145
|
+
end
|
146
|
+
|
147
|
+
protected
|
148
|
+
|
149
|
+
def includes_matching_messages_by?(flag, *args)
|
150
|
+
messages.send(flag).by(*args).any?
|
151
|
+
end
|
152
|
+
|
153
|
+
def includes_matching_messages_with_prep?(flag, preposition, *args)
|
154
|
+
messages.send(flag).receipts.flagged(preposition, *args).any?
|
158
155
|
end
|
159
156
|
end
|
160
157
|
end
|
@@ -1,6 +1,22 @@
|
|
1
1
|
module MessageTrain
|
2
2
|
# Ignore model
|
3
3
|
class Ignore < ActiveRecord::Base
|
4
|
+
IGNORE_METHODS = {
|
5
|
+
'Hash' => :ignore_hash,
|
6
|
+
'Array' => :ignore_array,
|
7
|
+
'String' => :ignore_id,
|
8
|
+
'Fixnum' => :ignore_id,
|
9
|
+
'MessageTrain::Conversation' => :ignore_conversation
|
10
|
+
}.freeze
|
11
|
+
|
12
|
+
UNIGNORE_METHODS = {
|
13
|
+
'Hash' => :unignore_hash,
|
14
|
+
'Array' => :unignore_array,
|
15
|
+
'String' => :unignore_id,
|
16
|
+
'Fixnum' => :unignore_id,
|
17
|
+
'MessageTrain::Conversation' => :unignore_conversation
|
18
|
+
}.freeze
|
19
|
+
|
4
20
|
belongs_to :participant, polymorphic: true
|
5
21
|
belongs_to(
|
6
22
|
:conversation,
|
@@ -14,11 +30,74 @@ module MessageTrain
|
|
14
30
|
where(participant: participant)
|
15
31
|
end)
|
16
32
|
|
17
|
-
|
33
|
+
scope :conversations, (lambda do
|
18
34
|
MessageTrain::Conversation.joins(:ignores)
|
19
|
-
|
20
|
-
|
21
|
-
|
35
|
+
.where(message_train_ignores: { id: where(nil) })
|
36
|
+
end)
|
37
|
+
|
38
|
+
def self.ignore(object, box)
|
39
|
+
method = IGNORE_METHODS[object.class.name]
|
40
|
+
return ignoring_error(object, box) if method.nil?
|
41
|
+
send(method, object, box)
|
42
|
+
end
|
43
|
+
|
44
|
+
def self.unignore(object, box)
|
45
|
+
method = UNIGNORE_METHODS[object.class.name]
|
46
|
+
return unignoring_error(object, box) if method.nil?
|
47
|
+
send(method, object, box)
|
48
|
+
end
|
49
|
+
|
50
|
+
def self.ignore_hash(object, box)
|
51
|
+
ignore object.values, box
|
52
|
+
end
|
53
|
+
|
54
|
+
def self.ignore_array(object, box)
|
55
|
+
object.collect { |item| ignore(item, box) }.uniq == [true]
|
56
|
+
end
|
57
|
+
|
58
|
+
def self.ignore_id(object, box)
|
59
|
+
ignore(box.find_conversation(object.to_i), box)
|
60
|
+
end
|
61
|
+
|
62
|
+
def self.ignore_conversation(object, box)
|
63
|
+
if box.authorize(object)
|
64
|
+
object.participant_ignore(box.participant)
|
65
|
+
box.results.add(object, :update_successful.l)
|
66
|
+
else
|
67
|
+
false
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
def self.ignoring_error(object, box)
|
72
|
+
box.errors.add(self, :cannot_ignore_type.l(type: object.class.name))
|
73
|
+
object
|
74
|
+
end
|
75
|
+
|
76
|
+
def self.unignore_hash(object, box)
|
77
|
+
unignore object.values, box
|
78
|
+
end
|
79
|
+
|
80
|
+
def self.unignore_array(object, box)
|
81
|
+
object.collect { |item| unignore(item, box) }.uniq == [true]
|
82
|
+
end
|
83
|
+
|
84
|
+
def self.unignore_id(object, box)
|
85
|
+
unignore(box.find_conversation(object.to_i), box)
|
86
|
+
end
|
87
|
+
|
88
|
+
def self.unignore_conversation(object, box)
|
89
|
+
if box.authorize(object)
|
90
|
+
object.participant_unignore(box.participant)
|
91
|
+
box.results.add(object, :update_successful.l)
|
92
|
+
object
|
93
|
+
else
|
94
|
+
false
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
def self.unignoring_error(object, box)
|
99
|
+
box.errors.add(self, :cannot_unignore_type.l(type: object.class.name))
|
100
|
+
object
|
22
101
|
end
|
23
102
|
end
|
24
103
|
end
|
@@ -4,15 +4,20 @@ module MessageTrain
|
|
4
4
|
# Serializations
|
5
5
|
serialize :recipients_to_save, Hash
|
6
6
|
|
7
|
+
attr_accessor :box
|
8
|
+
|
7
9
|
# Relationships
|
8
10
|
belongs_to(
|
9
11
|
:conversation,
|
10
12
|
foreign_key: :message_train_conversation_id,
|
13
|
+
class_name: 'MessageTrain::Conversation',
|
11
14
|
touch: true
|
12
15
|
)
|
13
16
|
belongs_to :sender, polymorphic: true
|
14
17
|
has_many :attachments, foreign_key: :message_train_message_id
|
15
18
|
has_many :receipts, foreign_key: :message_train_message_id
|
19
|
+
delegate :participant_ignored?, to: :conversation
|
20
|
+
delegate :send_receipts, to: :receipts
|
16
21
|
|
17
22
|
# Validations
|
18
23
|
validates_presence_of :sender, :subject
|
@@ -25,172 +30,116 @@ module MessageTrain
|
|
25
30
|
|
26
31
|
# Nested Attributes
|
27
32
|
accepts_nested_attributes_for(
|
28
|
-
:attachments,
|
29
|
-
reject_if: :all_blank,
|
30
|
-
allow_destroy: true
|
33
|
+
:attachments, reject_if: :all_blank, allow_destroy: true
|
31
34
|
)
|
32
35
|
|
33
36
|
# Scopes
|
34
|
-
default_scope { order(updated_at: :desc) }
|
35
37
|
scope :ready, -> { where(draft: false) }
|
36
38
|
scope :drafts, -> { where(draft: true) }
|
37
39
|
scope :by, ->(participant) { where(sender: participant) }
|
38
40
|
scope :drafts_by, ->(participant) { drafts.by(participant) }
|
39
41
|
scope :filter_by_receipt_method, (lambda do |receipt_method, participant|
|
40
|
-
|
41
|
-
id: where(nil).receipts.send(receipt_method, participant).message_ids
|
42
|
-
)
|
42
|
+
receipts.send(receipt_method, participant).messages
|
43
43
|
end)
|
44
|
+
scope :for_conversations, ->(c) { where conversation: c }
|
44
45
|
|
45
|
-
def
|
46
|
-
|
47
|
-
receipt_to_mark.present? && receipt_to_mark.mark(mark_to_set)
|
46
|
+
def self.conversation_ids
|
47
|
+
pluck(:message_train_conversation_id)
|
48
48
|
end
|
49
49
|
|
50
|
-
def self.
|
51
|
-
|
52
|
-
message.mark(mark_to_set, participant)
|
53
|
-
end
|
50
|
+
def self.conversations
|
51
|
+
MessageTrain::Conversation.where(id: conversation_ids)
|
54
52
|
end
|
55
53
|
|
56
|
-
def
|
57
|
-
|
58
|
-
receipts.recipient_receipt.each do |message|
|
59
|
-
recips << message.received_through
|
60
|
-
end
|
61
|
-
recips.uniq
|
54
|
+
def self.receipts
|
55
|
+
MessageTrain::Receipt.for_messages(ids)
|
62
56
|
end
|
63
57
|
|
64
|
-
def
|
65
|
-
|
58
|
+
def mark(mark_to_set, participant)
|
59
|
+
receipts.for(participant).mark(mark_to_set)
|
66
60
|
end
|
67
61
|
|
68
|
-
def self.
|
69
|
-
|
70
|
-
.where(message_train_messages: { id: where(nil) })
|
62
|
+
def self.mark(mark_to_set, participant)
|
63
|
+
find_each { |message| message.mark(mark_to_set, participant) }
|
71
64
|
end
|
72
65
|
|
73
|
-
def
|
74
|
-
|
75
|
-
.where(
|
76
|
-
message_train_messages: { id: where(nil) }
|
77
|
-
)
|
66
|
+
def recipients
|
67
|
+
receipts.recipient_receipt.map(&:received_through).uniq
|
78
68
|
end
|
79
69
|
|
80
|
-
def
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
70
|
+
def reply_recipients=(recipients)
|
71
|
+
recipient_arrays = {}
|
72
|
+
recipients.each do |recipient|
|
73
|
+
table_name = recipient.class.table_name
|
74
|
+
recipient_arrays[table_name] ||= []
|
75
|
+
recipient_arrays[table_name] << recipient.message_train_slug
|
76
|
+
end
|
77
|
+
recipient_arrays.each do |key, array|
|
78
|
+
recipients_to_save[key] = array.join(', ')
|
89
79
|
end
|
90
80
|
end
|
91
81
|
|
92
|
-
def
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
super
|
82
|
+
def method_missing(method_sym, *args, &block)
|
83
|
+
if method_sym.to_s =~ /^is_((.*)_(by|to|for|through))\?$/
|
84
|
+
return receipts.flagged(Regexp.last_match[1], *args).any?
|
85
|
+
end
|
86
|
+
if method_sym.to_s =~ /^mark_(.*)_for$/
|
87
|
+
return mark(Regexp.last_match[1], *args)
|
99
88
|
end
|
89
|
+
super
|
100
90
|
end
|
101
91
|
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
def respond_to?(method_sym, include_private = false)
|
106
|
-
if method_sym.to_s =~ /^is_.*_(by|to|for|through)\?$/ ||
|
107
|
-
method_sym.to_s =~ /^mark_.*_for\?$/
|
108
|
-
true
|
109
|
-
else
|
110
|
-
super
|
111
|
-
end
|
92
|
+
def self.method_missing(method_sym, *args, &block)
|
93
|
+
return super unless method_sym.to_s =~ /^with_(.*_(by|to|for|through))$/
|
94
|
+
filter_by_receipt_method(Regexp.last_match[1].to_sym, args.first)
|
112
95
|
end
|
113
96
|
|
114
|
-
def
|
115
|
-
if method_sym.to_s =~
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
97
|
+
def respond_to_missing?(method_sym, inc_private = false)
|
98
|
+
return true if method_sym.to_s =~ /^is_.*_(by|to|for|through)\?$/ ||
|
99
|
+
method_sym.to_s =~ /^mark_.*_for\?$/
|
100
|
+
super
|
101
|
+
end
|
102
|
+
|
103
|
+
def self.respond_to_missing?(method_sym, inc_private = false)
|
104
|
+
method_sym.to_s =~ /^.*_(by|to|for|through)$/ ? true : super
|
120
105
|
end
|
121
106
|
|
122
107
|
private
|
123
108
|
|
124
109
|
def create_conversation_if_blank
|
125
|
-
if conversation.
|
126
|
-
|
127
|
-
end
|
110
|
+
return if conversation.present?
|
111
|
+
self.conversation = Conversation.create(subject: subject)
|
128
112
|
end
|
129
113
|
|
130
114
|
def generate_sender_receipt
|
131
|
-
receipts.
|
132
|
-
recipient: sender,
|
133
|
-
received_through: sender,
|
134
|
-
sender: true
|
135
|
-
)
|
115
|
+
receipts.generate_for_sender(sender)
|
136
116
|
end
|
137
117
|
|
138
118
|
def generate_receipts_or_set_draft
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
if recipients.empty?
|
149
|
-
update_attribute :draft, true
|
150
|
-
else
|
151
|
-
conversation.update_attribute(:updated_at, Time.now)
|
152
|
-
end
|
153
|
-
end
|
119
|
+
return if draft
|
120
|
+
recipients_to_save.each { |table, slugs| save_recipients(table, slugs) }
|
121
|
+
recipients.empty? ? update_attribute(:draft, true) : conversation.touch
|
122
|
+
end
|
123
|
+
|
124
|
+
def save_recipients(table, slugs)
|
125
|
+
slugs = slugs.split(',')
|
126
|
+
slugs -= [sender.slug] if sender.class.table_name == table
|
127
|
+
slugs.each { |slug| send_receipts(table, slug) }
|
154
128
|
end
|
155
129
|
|
156
130
|
def set_conversation_subject_if_alone
|
157
|
-
if conversation.messages.count
|
158
|
-
|
159
|
-
end
|
131
|
+
return if conversation.messages.count != 1
|
132
|
+
conversation.update_attribute(:subject, subject)
|
160
133
|
end
|
161
134
|
|
162
135
|
def send_receipts(table, slug)
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
slug_column = MessageTrain.configuration
|
167
|
-
.slug_columns[table.to_sym] || :slug
|
168
|
-
if model.exists?(slug_column => slug)
|
169
|
-
recipient = model.find_by(slug_column => slug)
|
170
|
-
end_recipient_method = MessageTrain.configuration
|
171
|
-
.valid_recipients_methods[
|
172
|
-
table.to_sym
|
173
|
-
]
|
174
|
-
if end_recipient_method.nil?
|
175
|
-
unless conversation.participant_ignored?(recipient)
|
176
|
-
receipts.create!(
|
177
|
-
recipient: recipient,
|
178
|
-
received_through: recipient
|
179
|
-
)
|
180
|
-
end
|
181
|
-
else
|
182
|
-
recipient.send(end_recipient_method).uniq.each do |end_recipient|
|
183
|
-
next if conversation.participant_ignored?(end_recipient) ||
|
184
|
-
end_recipient == sender
|
185
|
-
receipts.create!(
|
186
|
-
recipient: end_recipient,
|
187
|
-
received_through: recipient
|
188
|
-
)
|
189
|
-
end
|
190
|
-
end
|
191
|
-
else
|
136
|
+
model = table.classify.constantize
|
137
|
+
recipient = model.find_by_message_train_slug(slug)
|
138
|
+
unless recipient.present?
|
192
139
|
errors.add :recipients_to_save, :name_not_found.l(name: slug)
|
140
|
+
return
|
193
141
|
end
|
142
|
+
receipts.send_to_or_through(recipient)
|
194
143
|
end
|
195
144
|
end
|
196
145
|
end
|