mailboxer-without-notification 0.11.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (107) hide show
  1. data/.gitignore +18 -0
  2. data/.rspec +1 -0
  3. data/.travis.yml +11 -0
  4. data/.yardopts +2 -0
  5. data/Appraisals +19 -0
  6. data/Gemfile +3 -0
  7. data/LICENSE.txt +21 -0
  8. data/README.md +298 -0
  9. data/Rakefile +11 -0
  10. data/app/mailers/message_mailer.rb +37 -0
  11. data/app/models/conversation.rb +179 -0
  12. data/app/models/mailbox.rb +122 -0
  13. data/app/models/message.rb +218 -0
  14. data/app/models/receipt.rb +176 -0
  15. data/app/uploaders/attachment_uploader.rb +3 -0
  16. data/app/views/message_mailer/new_message_email.html.erb +20 -0
  17. data/app/views/message_mailer/new_message_email.text.erb +10 -0
  18. data/app/views/message_mailer/reply_message_email.html.erb +20 -0
  19. data/app/views/message_mailer/reply_message_email.text.erb +10 -0
  20. data/config/locales/en.yml +7 -0
  21. data/config/locales/fr.yml +7 -0
  22. data/db/migrate/20110511145103_create_mailboxer.rb +61 -0
  23. data/db/migrate/20110719110700_add_notified_object.rb +17 -0
  24. data/db/migrate/20110912163911_add_notification_code.rb +13 -0
  25. data/db/migrate/20111204163911_add_attachments.rb +9 -0
  26. data/db/migrate/20120813110712_rename_receipts_read.rb +9 -0
  27. data/db/migrate/20130305144212_add_global_notification_support.rb +9 -0
  28. data/db/migrate/20131003144212_change_table_notification.rb +10 -0
  29. data/db/migrate/20131003214212_change_relations.rb +6 -0
  30. data/gemfiles/rails3.0.gemfile +8 -0
  31. data/gemfiles/rails3.1.gemfile +8 -0
  32. data/gemfiles/rails3.2.gemfile +8 -0
  33. data/gemfiles/rails4.0.gemfile +8 -0
  34. data/lib/generators/mailboxer/install_generator.rb +35 -0
  35. data/lib/generators/mailboxer/templates/initializer.rb +17 -0
  36. data/lib/generators/mailboxer/views_generator.rb +9 -0
  37. data/lib/mailboxer.rb +37 -0
  38. data/lib/mailboxer/concerns/configurable_mailer.rb +13 -0
  39. data/lib/mailboxer/engine.rb +17 -0
  40. data/lib/mailboxer/models/messageable.rb +225 -0
  41. data/mailboxer.gemspec +49 -0
  42. data/spec/dummy/.gitignore +5 -0
  43. data/spec/dummy/Gemfile +33 -0
  44. data/spec/dummy/Rakefile +7 -0
  45. data/spec/dummy/app/controllers/application_controller.rb +3 -0
  46. data/spec/dummy/app/controllers/home_controller.rb +4 -0
  47. data/spec/dummy/app/helpers/application_helper.rb +2 -0
  48. data/spec/dummy/app/mailers/.gitkeep +0 -0
  49. data/spec/dummy/app/models/.gitkeep +0 -0
  50. data/spec/dummy/app/models/cylon.rb +7 -0
  51. data/spec/dummy/app/models/duck.rb +11 -0
  52. data/spec/dummy/app/models/user.rb +6 -0
  53. data/spec/dummy/app/views/home/index.html.haml +7 -0
  54. data/spec/dummy/app/views/layouts/application.html.haml +11 -0
  55. data/spec/dummy/config.ru +4 -0
  56. data/spec/dummy/config/application.rb +42 -0
  57. data/spec/dummy/config/boot.rb +10 -0
  58. data/spec/dummy/config/database.yml +24 -0
  59. data/spec/dummy/config/environment.rb +5 -0
  60. data/spec/dummy/config/environments/development.rb +26 -0
  61. data/spec/dummy/config/environments/production.rb +49 -0
  62. data/spec/dummy/config/environments/test.rb +33 -0
  63. data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
  64. data/spec/dummy/config/initializers/inflections.rb +10 -0
  65. data/spec/dummy/config/initializers/mailboxer.rb +17 -0
  66. data/spec/dummy/config/initializers/mime_types.rb +5 -0
  67. data/spec/dummy/config/initializers/secret_token.rb +7 -0
  68. data/spec/dummy/config/initializers/session_store.rb +8 -0
  69. data/spec/dummy/config/locales/en.yml +5 -0
  70. data/spec/dummy/config/routes.rb +58 -0
  71. data/spec/dummy/config/sunspot.yml +17 -0
  72. data/spec/dummy/db/migrate/20110228120600_create_users.rb +14 -0
  73. data/spec/dummy/db/migrate/20110306002940_create_ducks.rb +14 -0
  74. data/spec/dummy/db/migrate/20110306015107_create_cylons.rb +14 -0
  75. data/spec/dummy/db/migrate/20120305103200_create_mailboxer.rb +61 -0
  76. data/spec/dummy/db/migrate/20120305103201_add_notified_object.rb +17 -0
  77. data/spec/dummy/db/migrate/20120305103202_add_notification_code.rb +13 -0
  78. data/spec/dummy/db/migrate/20120305103203_add_attachments.rb +5 -0
  79. data/spec/dummy/db/migrate/20120813110712_rename_receipts_read.rb +9 -0
  80. data/spec/dummy/db/migrate/20130305144212_add_global_notification_support.rb +11 -0
  81. data/spec/dummy/db/migrate/20131003144212_change_table_notification.rb +10 -0
  82. data/spec/dummy/db/migrate/20131003214212_change_relations.rb +6 -0
  83. data/spec/dummy/db/schema.rb +74 -0
  84. data/spec/dummy/public/404.html +26 -0
  85. data/spec/dummy/public/422.html +26 -0
  86. data/spec/dummy/public/500.html +26 -0
  87. data/spec/dummy/public/favicon.ico +0 -0
  88. data/spec/dummy/public/index.html +239 -0
  89. data/spec/dummy/public/robots.txt +5 -0
  90. data/spec/dummy/public/uploads/testfile.txt +1 -0
  91. data/spec/dummy/script/rails +6 -0
  92. data/spec/factories/cylon.rb +10 -0
  93. data/spec/factories/duck.rb +10 -0
  94. data/spec/factories/user.rb +10 -0
  95. data/spec/integration/message_and_receipt_spec.rb +903 -0
  96. data/spec/integration/navigation_spec.rb +9 -0
  97. data/spec/mailboxer/concerns/configurable_mailer_spec.rb +27 -0
  98. data/spec/mailboxer_spec.rb +7 -0
  99. data/spec/mailers/message_mailer_spec.rb +109 -0
  100. data/spec/models/conversation_spec.rb +154 -0
  101. data/spec/models/mailbox_spec.rb +160 -0
  102. data/spec/models/mailboxer_models_messageable_spec.rb +324 -0
  103. data/spec/models/message_spec.rb +222 -0
  104. data/spec/models/receipt_spec.rb +56 -0
  105. data/spec/spec_helper.rb +36 -0
  106. data/spec/testfile.txt +1 -0
  107. metadata +301 -0
@@ -0,0 +1,122 @@
1
+ class Mailbox
2
+ attr_accessor :type
3
+ attr_reader :messageable
4
+
5
+ #Initializer method
6
+ def initialize(messageable)
7
+ @messageable = messageable
8
+ end
9
+
10
+ #Returns the notifications for the messageable
11
+ def notifications(options = {})
12
+ #:type => nil is a hack not to give Messages as Notifications
13
+ notifs = Message.recipient(@messageable).order("messages.created_at DESC")
14
+ if (options[:read].present? and options[:read]==false) or (options[:unread].present? and options[:unread]==true)
15
+ notifs = notifs.unread
16
+ end
17
+
18
+ notifs
19
+ end
20
+
21
+ #Returns the conversations for the messageable
22
+ #
23
+ #Options
24
+ #
25
+ #* :mailbox_type
26
+ # * "inbox"
27
+ # * "sentbox"
28
+ # * "trash"
29
+ #
30
+ #* :read=false
31
+ #* :unread=true
32
+ #
33
+ def conversations(options = {})
34
+ conv = Conversation.participant(@messageable)
35
+
36
+ if options[:mailbox_type].present?
37
+ case options[:mailbox_type]
38
+ when 'inbox'
39
+ conv = Conversation.inbox(@messageable)
40
+ when 'sentbox'
41
+ conv = Conversation.sentbox(@messageable)
42
+ when 'trash'
43
+ conv = Conversation.trash(@messageable)
44
+ when 'not_trash'
45
+ conv = Conversation.not_trash(@messageable)
46
+ end
47
+ end
48
+
49
+ if (options.has_key?(:read) && options[:read]==false) || (options.has_key?(:unread) && options[:unread]==true)
50
+ conv = conv.unread(@messageable)
51
+ end
52
+
53
+ conv
54
+ end
55
+
56
+ #Returns the conversations in the inbox of messageable
57
+ #
58
+ #Same as conversations({:mailbox_type => 'inbox'})
59
+ def inbox(options={})
60
+ options = options.merge(:mailbox_type => 'inbox')
61
+ self.conversations(options)
62
+ end
63
+
64
+ #Returns the conversations in the sentbox of messageable
65
+ #
66
+ #Same as conversations({:mailbox_type => 'sentbox'})
67
+ def sentbox(options={})
68
+ options = options.merge(:mailbox_type => 'sentbox')
69
+ self.conversations(options)
70
+ end
71
+
72
+ #Returns the conversations in the trash of messageable
73
+ #
74
+ #Same as conversations({:mailbox_type => 'trash'})
75
+ def trash(options={})
76
+ options = options.merge(:mailbox_type => 'trash')
77
+ self.conversations(options)
78
+ end
79
+
80
+ #Returns all the receipts of messageable, from Messages and Notifications
81
+ def receipts(options = {})
82
+ Receipt.where(options).recipient(@messageable)
83
+ end
84
+
85
+ #Deletes all the messages in the trash of messageable. NOT IMPLEMENTED.
86
+ def empty_trash(options = {})
87
+ #TODO
88
+ false
89
+ end
90
+
91
+ #Returns if messageable is a participant of conversation
92
+ def has_conversation?(conversation)
93
+ conversation.is_participant?(@messageable)
94
+ end
95
+
96
+ #Returns true if messageable has at least one trashed message of the conversation
97
+ def is_trashed?(conversation)
98
+ conversation.is_trashed?(@messageable)
99
+ end
100
+
101
+ #Returns true if messageable has trashed all the messages of the conversation
102
+ def is_completely_trashed?(conversation)
103
+ conversation.is_completely_trashed?(@messageable)
104
+ end
105
+
106
+ #Returns the receipts of object for messageable as a ActiveRecord::Relation
107
+ #
108
+ #Object can be:
109
+ #* A Message
110
+ #* A Notification
111
+ #* A Conversation
112
+ #
113
+ #If object isn't one of the above, a nil will be returned
114
+ def receipts_for(object)
115
+ case object
116
+ when Message#, Notification
117
+ object.receipt_for(@messageable)
118
+ when Conversation
119
+ object.receipts_for(@messageable)
120
+ end
121
+ end
122
+ end
@@ -0,0 +1,218 @@
1
+ class Message < ActiveRecord::Base
2
+ #AJOUT DEPUIS NOTIFICATION
3
+ attr_accessor :recipients
4
+ attr_accessible :body, :subject, :global, :expires if Mailboxer.protected_attributes?
5
+
6
+ belongs_to :sender, :polymorphic => :true
7
+ #belongs_to :notified_object, :polymorphic => :true
8
+ has_many :receipts, :dependent => :destroy
9
+
10
+ validates_presence_of :body#, :subject
11
+ #FIN NOTIFICATION
12
+ attr_accessible :attachment if Mailboxer.protected_attributes?
13
+
14
+ belongs_to :conversation, :validate => true, :autosave => true
15
+ validates_presence_of :sender
16
+
17
+ class_attribute :on_deliver_callback
18
+ protected :on_deliver_callback
19
+ scope :conversation, lambda { |conversation|
20
+ where(:conversation_id => conversation.id)
21
+ }
22
+ #AJOUT DEPUIS NOTIFICATION + modification de notifications en messages
23
+ scope :recipient, lambda { |recipient|
24
+ joins(:receipts).where('receipts.receiver_id' => recipient.id,'receipts.receiver_type' => recipient.class.base_class.to_s)
25
+ }
26
+ #scope :with_object, lambda { |obj|
27
+ # where('notified_object_id' => obj.id,'notified_object_type' => obj.class.to_s)
28
+ #}
29
+ scope :not_trashed, lambda {
30
+ joins(:receipts).where('receipts.trashed' => false)
31
+ }
32
+ scope :unread, lambda {
33
+ joins(:receipts).where('receipts.is_read' => false)
34
+ }
35
+ scope :global, lambda { where(:global => true) }
36
+ scope :expired, lambda { where("messages.expires < ?", Time.now) }
37
+ scope :unexpired, lambda {
38
+ where("messages.expires is NULL OR messages.expires > ?", Time.now)
39
+ }
40
+ #FIN NOTIFICATION
41
+
42
+ mount_uploader :attachment, AttachmentUploader
43
+
44
+ include Concerns::ConfigurableMailer
45
+
46
+ class << self
47
+ #Sets the on deliver callback method.
48
+ def on_deliver(callback_method)
49
+ self.on_deliver_callback = callback_method
50
+ end
51
+
52
+ ##Sends a Notification to all the recipients
53
+ #def notify_all(recipients,subject,body,obj = nil,sanitize_text = true,notification_code=nil,send_mail=true)
54
+ # notification = Notification.new({:body => body, :subject => subject})
55
+ # notification.recipients = recipients.respond_to?(:each) ? recipients : [recipients]
56
+ # notification.recipients = notification.recipients.uniq if recipients.respond_to?(:uniq)
57
+ # notification.notified_object = obj if obj.present?
58
+ # notification.notification_code = notification_code if notification_code.present?
59
+ # notification.deliver sanitize_text, send_mail
60
+ #end
61
+ #
62
+ ##Takes a +Receipt+ or an +Array+ of them and returns +true+ if the delivery was
63
+ ##successful or +false+ if some error raised
64
+ #def successful_delivery? receipts
65
+ # case receipts
66
+ # when Receipt
67
+ # receipts.valid?
68
+ # receipts.errors.empty?
69
+ # when Array
70
+ # receipts.each(&:valid?)
71
+ # receipts.all? { |t| t.errors.empty? }
72
+ # else
73
+ # false
74
+ # end
75
+ #end
76
+ end
77
+
78
+ #Delivers a Message. USE NOT RECOMENDED.
79
+ #Use Mailboxer::Models::Message.send_message instead.
80
+ def deliver(reply = false, should_clean = true)
81
+ self.clean if should_clean
82
+
83
+ #Receiver receipts
84
+ temp_receipts = recipients.map { |r| build_receipt(r, 'inbox') }
85
+
86
+ #Sender receipt
87
+ sender_receipt = build_receipt(sender, 'sentbox', true)
88
+ temp_receipts << sender_receipt
89
+
90
+ temp_receipts.each(&:valid?)
91
+ if temp_receipts.all? { |t| t.errors.empty? }
92
+ temp_receipts.each(&:save!) #Save receipts
93
+ #Should send an email?
94
+ if Mailboxer.uses_emails
95
+ if Mailboxer.mailer_wants_array
96
+ get_mailer.send_email(self, recipients).deliver
97
+ else
98
+ recipients.each do |recipient|
99
+ email_to = recipient.send(Mailboxer.email_method, self)
100
+ get_mailer.send_email(self, recipient).deliver if email_to.present?
101
+ end
102
+ end
103
+ end
104
+ if reply
105
+ self.conversation.touch
106
+ end
107
+ self.recipients=nil
108
+ self.on_deliver_callback.call(self) unless self.on_deliver_callback.nil?
109
+ end
110
+ sender_receipt
111
+ end
112
+
113
+ #AJOUT DEPUIS NOTIFICATION
114
+ #Returns the recipients of the message
115
+ def recipients
116
+ if @recipients.blank?
117
+ recipients_array = Array.new
118
+ self.receipts.each do |receipt|
119
+ recipients_array << receipt.receiver
120
+ end
121
+
122
+ recipients_array
123
+ else
124
+ @recipients
125
+ end
126
+ end
127
+
128
+ #Returns the receipt for the participant
129
+ def receipt_for(participant)
130
+ Receipt.message(self).recipient(participant)
131
+ end
132
+
133
+ #Returns the receipt for the participant. Alias for receipt_for(participant)
134
+ def receipts_for(participant)
135
+ receipt_for(participant)
136
+ end
137
+
138
+ #Returns if the participant have read the message
139
+ def is_unread?(participant)
140
+ return false if participant.nil?
141
+ !self.receipt_for(participant).first.is_read
142
+ end
143
+
144
+ def is_read?(participant)
145
+ !self.is_unread?(participant)
146
+ end
147
+
148
+ #Returns if the participant have trashed the message
149
+ def is_trashed?(participant)
150
+ return false if participant.nil?
151
+ self.receipt_for(participant).first.trashed
152
+ end
153
+
154
+ #Returns if the participant have deleted the message
155
+ def is_deleted?(participant)
156
+ return false if participant.nil?
157
+ return self.receipt_for(participant).first.deleted
158
+ end
159
+
160
+ #Mark the message as read
161
+ def mark_as_read(participant)
162
+ return if participant.nil?
163
+ self.receipt_for(participant).mark_as_read
164
+ end
165
+
166
+ #Mark the message as unread
167
+ def mark_as_unread(participant)
168
+ return if participant.nil?
169
+ self.receipt_for(participant).mark_as_unread
170
+ end
171
+
172
+ #Move the message to the trash
173
+ def move_to_trash(participant)
174
+ return if participant.nil?
175
+ self.receipt_for(participant).move_to_trash
176
+ end
177
+
178
+ #Takes the message out of the trash
179
+ def untrash(participant)
180
+ return if participant.nil?
181
+ self.receipt_for(participant).untrash
182
+ end
183
+
184
+ #Mark the message as deleted for one of the participant
185
+ def mark_as_deleted(participant)
186
+ return if participant.nil?
187
+ return self.receipt_for(participant).mark_as_deleted
188
+ end
189
+
190
+ include ActionView::Helpers::SanitizeHelper
191
+
192
+ #Sanitizes the body and subject
193
+ def clean
194
+ unless self.subject.nil?
195
+ self.subject = sanitize self.subject
196
+ end
197
+ self.body = sanitize self.body
198
+ end
199
+
200
+ #Returns notified_object. DEPRECATED
201
+ def object
202
+ warn "DEPRECATION WARNING: use 'notify_object' instead of 'object' to get the object associated with the Message"
203
+ notified_object
204
+ end
205
+
206
+ #FIN NOTIFICATION
207
+
208
+ private
209
+ def build_receipt(receiver, mailbox_type, is_read = false)
210
+ Receipt.new.tap do |receipt|
211
+ #mis message à la place de notification
212
+ receipt.message = self
213
+ receipt.is_read = is_read
214
+ receipt.receiver = receiver
215
+ receipt.mailbox_type = mailbox_type
216
+ end
217
+ end
218
+ end
@@ -0,0 +1,176 @@
1
+ class Receipt < ActiveRecord::Base
2
+ attr_accessible :trashed, :is_read, :deleted if Mailboxer.protected_attributes?
3
+
4
+ #belongs_to :notification, :validate => true, :autosave => true
5
+ belongs_to :message, :validate => true, :autosave => true#, :foreign_key => "message_id"
6
+ belongs_to :receiver, :polymorphic => :true
7
+ #belongs_to :message, :foreign_key => "notification_id"
8
+
9
+ validates_presence_of :receiver
10
+
11
+ scope :recipient, lambda { |recipient|
12
+ where(:receiver_id => recipient.id,:receiver_type => recipient.class.base_class.to_s)
13
+ }
14
+ #Notifications Scope checks type to be nil, not Notification because of STI behaviour
15
+ #with the primary class (no type is saved)
16
+ #scope :notifications_receipts, lambda { joins(:notification).where('notifications.type' => nil) }
17
+ #scope :messages_receipts, lambda { joins(:message).where('messages.type' => Message.to_s) }
18
+ scope :messages_receipts, lambda { joins(:message) }
19
+
20
+ scope :message, lambda { |message|
21
+ where(:message_id => message.id)
22
+ }
23
+ scope :conversation, lambda { |conversation|
24
+ joins(:message).where('messages.conversation_id' => conversation.id)
25
+ }
26
+ scope :sentbox, lambda { where(:mailbox_type => "sentbox") }
27
+ scope :inbox, lambda { where(:mailbox_type => "inbox") }
28
+ scope :trash, lambda { where(:trashed => true, :deleted => false) }
29
+ scope :not_trash, lambda { where(:trashed => false) }
30
+ scope :deleted, lambda { where(:deleted => true) }
31
+ scope :not_deleted, lambda { where(:deleted => false) }
32
+ scope :is_read, lambda { where(:is_read => true) }
33
+ scope :is_unread, lambda { where(:is_read => false) }
34
+
35
+ after_validation :remove_duplicate_errors
36
+ class << self
37
+ #Marks all the receipts from the relation as read
38
+ def mark_as_read(options={})
39
+ update_receipts({:is_read => true}, options)
40
+ end
41
+
42
+ #Marks all the receipts from the relation as unread
43
+ def mark_as_unread(options={})
44
+ update_receipts({:is_read => false}, options)
45
+ end
46
+
47
+ #Marks all the receipts from the relation as trashed
48
+ def move_to_trash(options={})
49
+ update_receipts({:trashed => true}, options)
50
+ end
51
+
52
+ #Marks all the receipts from the relation as not trashed
53
+ def untrash(options={})
54
+ update_receipts({:trashed => false}, options)
55
+ end
56
+
57
+ #Marks the receipt as deleted
58
+ def mark_as_deleted(options={})
59
+ update_receipts({:deleted => true}, options)
60
+ end
61
+
62
+ #Marks the receipt as not deleted
63
+ def mark_as_not_deleted(options={})
64
+ update_receipts({:deleted => false}, options)
65
+ end
66
+
67
+ #Moves all the receipts from the relation to inbox
68
+ def move_to_inbox(options={})
69
+ update_receipts({:mailbox_type => :inbox, :trashed => false}, options)
70
+ end
71
+
72
+ #Moves all the receipts from the relation to sentbox
73
+ def move_to_sentbox(options={})
74
+ update_receipts({:mailbox_type => :sentbox, :trashed => false}, options)
75
+ end
76
+
77
+ #This methods helps to do a update_all with table joins, not currently supported by rails.
78
+ #Acording to the github ticket https://github.com/rails/rails/issues/522 it should be
79
+ #supported with 3.2.
80
+ def update_receipts(updates,options={})
81
+ ids = Array.new
82
+ where(options).each do |rcp|
83
+ ids << rcp.id
84
+ end
85
+ unless ids.empty?
86
+ conditions = [""].concat(ids)
87
+ condition = "id = ? "
88
+ ids.drop(1).each do
89
+ condition << "OR id = ? "
90
+ end
91
+ conditions[0] = condition
92
+ Receipt.except(:where).except(:joins).where(conditions).update_all(updates)
93
+ end
94
+ end
95
+ end
96
+
97
+
98
+ #Marks the receipt as deleted
99
+ def mark_as_deleted
100
+ update_attributes(:deleted => true)
101
+ end
102
+
103
+ #Marks the receipt as not deleted
104
+ def mark_as_not_deleted
105
+ update_attributes(:deleted => false)
106
+ end
107
+
108
+ #Marks the receipt as read
109
+ def mark_as_read
110
+ update_attributes(:is_read => true)
111
+ end
112
+
113
+ #Marks the receipt as unread
114
+ def mark_as_unread
115
+ update_attributes(:is_read => false)
116
+ end
117
+
118
+ #Marks the receipt as trashed
119
+ def move_to_trash
120
+ update_attributes(:trashed => true)
121
+ end
122
+
123
+ #Marks the receipt as not trashed
124
+ def untrash
125
+ update_attributes(:trashed => false)
126
+ end
127
+
128
+ #Moves the receipt to inbox
129
+ def move_to_inbox
130
+ update_attributes(:mailbox_type => :inbox, :trashed => false)
131
+ end
132
+
133
+ #Moves the receipt to sentbox
134
+ def move_to_sentbox
135
+ update_attributes(:mailbox_type => :sentbox, :trashed => false)
136
+ end
137
+
138
+ #Returns the conversation associated to the receipt if the notification is a Message
139
+ def conversation
140
+ message.conversation #if message.is_a? Message
141
+ end
142
+
143
+ #Returns if the participant have read the message
144
+ def is_unread?
145
+ !self.is_read
146
+ end
147
+
148
+ #Returns if the participant have trashed the message
149
+ def is_trashed?
150
+ self.trashed
151
+ end
152
+
153
+ protected
154
+
155
+ #Removes the duplicate error about not present subject from Conversation if it has been already
156
+ #raised by Message
157
+ def remove_duplicate_errors
158
+ if self.errors["message.conversation.subject"].present? and self.errors["message.subject"].present?
159
+ self.errors["message.conversation.subject"].each do |msg|
160
+ self.errors["message.conversation.subject"].delete(msg)
161
+ end
162
+ end
163
+ end
164
+
165
+ if Mailboxer.search_enabled
166
+ searchable do
167
+ text :subject, :boost => 5 do
168
+ message.subject if message
169
+ end
170
+ text :body do
171
+ message.body if message
172
+ end
173
+ integer :receiver_id
174
+ end
175
+ end
176
+ end