acts-as-messageable 0.4.7 → 0.4.8
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.
- data/.rspec +1 -1
- data/Gemfile +12 -12
- data/README.md +278 -265
- data/VERSION +1 -1
- data/acts-as-messageable.gemspec +2 -2
- data/lib/acts-as-messageable.rb +7 -7
- data/lib/acts-as-messageable/message.rb +97 -95
- data/lib/acts-as-messageable/model.rb +165 -157
- data/lib/acts-as-messageable/relation.rb +4 -0
- data/spec/acts-as-messageable_spec.rb +266 -234
- data/spec/custom-class_spec.rb +19 -4
- data/spec/spec_helper.rb +65 -61
- data/spec/support/admin.rb +3 -3
- data/spec/support/user.rb +7 -7
- metadata +3 -3
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.4.
|
1
|
+
0.4.8
|
data/acts-as-messageable.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = "acts-as-messageable"
|
8
|
-
s.version = "0.4.
|
8
|
+
s.version = "0.4.8"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Piotr Nielacny"]
|
12
|
-
s.date = "
|
12
|
+
s.date = "2013-02-05"
|
13
13
|
s.email = "piotr.nielacny@gmail.com"
|
14
14
|
s.extra_rdoc_files = [
|
15
15
|
"README.md"
|
data/lib/acts-as-messageable.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
|
-
module ActsAsMessageable
|
2
|
-
autoload :Model, 'acts-as-messageable/model'
|
3
|
-
autoload :Message, 'acts-as-messageable/message'
|
4
|
-
autoload :Relation, 'acts-as-messageable/relation'
|
5
|
-
end
|
6
|
-
|
7
|
-
require 'acts-as-messageable/railtie'
|
1
|
+
module ActsAsMessageable
|
2
|
+
autoload :Model, 'acts-as-messageable/model'
|
3
|
+
autoload :Message, 'acts-as-messageable/message'
|
4
|
+
autoload :Relation, 'acts-as-messageable/relation'
|
5
|
+
end
|
6
|
+
|
7
|
+
require 'acts-as-messageable/railtie'
|
@@ -1,95 +1,97 @@
|
|
1
|
-
require 'ancestry'
|
2
|
-
|
3
|
-
module ActsAsMessageable
|
4
|
-
class Message < ::ActiveRecord::Base
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
:
|
12
|
-
:
|
13
|
-
:
|
14
|
-
:
|
15
|
-
:
|
16
|
-
:
|
17
|
-
:
|
18
|
-
:
|
19
|
-
:
|
20
|
-
:
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
scope :
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
:
|
44
|
-
:
|
45
|
-
:
|
46
|
-
:
|
47
|
-
:
|
48
|
-
:
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
scope :
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
alias :
|
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
|
-
end
|
1
|
+
require 'ancestry'
|
2
|
+
|
3
|
+
module ActsAsMessageable
|
4
|
+
class Message < ::ActiveRecord::Base
|
5
|
+
belongs_to :received_messageable, :polymorphic => true
|
6
|
+
belongs_to :sent_messageable, :polymorphic => true
|
7
|
+
|
8
|
+
attr_accessible :topic,
|
9
|
+
:body,
|
10
|
+
:received_messageable_type,
|
11
|
+
:received_messageable_id,
|
12
|
+
:sent_messageable_type,
|
13
|
+
:sent_messageable_id,
|
14
|
+
:opened,
|
15
|
+
:recipient_delete,
|
16
|
+
:sender_delete,
|
17
|
+
:recipient_permanent_delete,
|
18
|
+
:sender_permanent_delete,
|
19
|
+
:created_at,
|
20
|
+
:updated_at
|
21
|
+
|
22
|
+
attr_accessor :removed, :restored
|
23
|
+
cattr_accessor :required
|
24
|
+
|
25
|
+
|
26
|
+
# Sample documentation for scope
|
27
|
+
default_scope order("created_at desc")
|
28
|
+
scope :are_from, lambda { |*args| where(:sent_messageable_id => args.first, :sent_messageable_type => args.first.class.name) }
|
29
|
+
scope :are_to, lambda { |*args| where(:received_messageable_id => args.first, :received_messageable_type => args.first.class.name) }
|
30
|
+
scope :with_id, lambda { |*args|
|
31
|
+
ActiveSupport::Deprecation.warn("Calling with_id is deprecated. Please use `find` instead.")
|
32
|
+
where(:id => args.first)
|
33
|
+
}
|
34
|
+
|
35
|
+
scope :connected_with, lambda { |*args| where("(sent_messageable_type = :sent_type and
|
36
|
+
sent_messageable_id = :sent_id and
|
37
|
+
sender_delete = :s_delete and sender_permanent_delete = :s_perm_delete) or
|
38
|
+
(received_messageable_type = :received_type and
|
39
|
+
received_messageable_id = :received_id and
|
40
|
+
recipient_delete = :r_delete and recipient_permanent_delete = :r_perm_delete)",
|
41
|
+
:sent_type => args.first.class.resolve_active_record_ancestor.to_s,
|
42
|
+
:sent_id => args.first.id,
|
43
|
+
:received_type => args.first.class.resolve_active_record_ancestor.to_s,
|
44
|
+
:received_id => args.first.id,
|
45
|
+
:r_delete => args.last,
|
46
|
+
:s_delete => args.last,
|
47
|
+
:r_perm_delete => false,
|
48
|
+
:s_perm_delete => false)
|
49
|
+
}
|
50
|
+
scope :readed, lambda { where(:opened => true) }
|
51
|
+
scope :unreaded, lambda { where(:opened => false) }
|
52
|
+
scope :deleted, lambda { where(:recipient_delete => true, :sender_delete => true) }
|
53
|
+
|
54
|
+
def open?
|
55
|
+
self.opened?
|
56
|
+
end
|
57
|
+
|
58
|
+
def open
|
59
|
+
update_attributes!(:opened => true)
|
60
|
+
end
|
61
|
+
alias :mark_as_read :open
|
62
|
+
alias :read :open
|
63
|
+
|
64
|
+
def close
|
65
|
+
update_attributes!(:opened => false)
|
66
|
+
end
|
67
|
+
alias :mark_as_unread :close
|
68
|
+
alias :unread :close
|
69
|
+
|
70
|
+
alias :from :sent_messageable
|
71
|
+
alias :to :received_messageable
|
72
|
+
|
73
|
+
def real_receiver(user)
|
74
|
+
user == from ? to : from
|
75
|
+
end
|
76
|
+
|
77
|
+
def participant?(user)
|
78
|
+
(to == user) || (from == user)
|
79
|
+
end
|
80
|
+
|
81
|
+
def conversation
|
82
|
+
root.subtree
|
83
|
+
end
|
84
|
+
|
85
|
+
def delete
|
86
|
+
self.removed = true
|
87
|
+
end
|
88
|
+
|
89
|
+
def restore
|
90
|
+
self.restored = true
|
91
|
+
end
|
92
|
+
|
93
|
+
def reply(*args)
|
94
|
+
to.reply_to(self, *args)
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
@@ -1,157 +1,165 @@
|
|
1
|
-
module ActsAsMessageable
|
2
|
-
module Model
|
3
|
-
|
4
|
-
def self.included(base)
|
5
|
-
base.extend ClassMethods
|
6
|
-
end
|
7
|
-
|
8
|
-
module ClassMethods
|
9
|
-
mattr_accessor :messages_class_name
|
10
|
-
|
11
|
-
# Method make ActiveRecord::Base object messageable
|
12
|
-
# @param [Symbol] :table_name - table name for messages
|
13
|
-
# @param [String] :class_name - message class name
|
14
|
-
# @param [Array, Symbol] :required - required fields in message
|
15
|
-
# @param [Symbol] :dependent - dependent option from ActiveRecord has_many method
|
16
|
-
def acts_as_messageable(options = {})
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
self.messages_class_name.
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
result
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
result
|
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
|
-
|
1
|
+
module ActsAsMessageable
|
2
|
+
module Model
|
3
|
+
|
4
|
+
def self.included(base)
|
5
|
+
base.extend ClassMethods
|
6
|
+
end
|
7
|
+
|
8
|
+
module ClassMethods
|
9
|
+
mattr_accessor :messages_class_name
|
10
|
+
|
11
|
+
# Method make ActiveRecord::Base object messageable
|
12
|
+
# @param [Symbol] :table_name - table name for messages
|
13
|
+
# @param [String] :class_name - message class name
|
14
|
+
# @param [Array, Symbol] :required - required fields in message
|
15
|
+
# @param [Symbol] :dependent - dependent option from ActiveRecord has_many method
|
16
|
+
def acts_as_messageable(options = {})
|
17
|
+
default_options = {
|
18
|
+
:table_name => "messages",
|
19
|
+
:class_name => "ActsAsMessageable::Message",
|
20
|
+
:required => [:topic, :body],
|
21
|
+
:dependent => :nullify,
|
22
|
+
}
|
23
|
+
options = default_options.merge(options)
|
24
|
+
|
25
|
+
has_many :received_messages_relation,
|
26
|
+
:as => :received_messageable,
|
27
|
+
:class_name => options[:class_name],
|
28
|
+
:dependent => options[:dependent]
|
29
|
+
has_many :sent_messages_relation,
|
30
|
+
:as => :sent_messageable,
|
31
|
+
:class_name => options[:class_name],
|
32
|
+
:dependent => options[:dependent]
|
33
|
+
|
34
|
+
self.messages_class_name = options[:class_name].constantize
|
35
|
+
self.messages_class_name.has_ancestry
|
36
|
+
|
37
|
+
if self.messages_class_name.respond_to?(:table_name=)
|
38
|
+
self.messages_class_name.table_name = options[:table_name]
|
39
|
+
else
|
40
|
+
self.messages_class_name.set_table_name(options[:table_name])
|
41
|
+
ActiveSupport::Deprecation.warn("Calling set_table_name is deprecated. Please use `self.table_name = 'the_name'` instead.")
|
42
|
+
end
|
43
|
+
|
44
|
+
self.messages_class_name.required = Array.wrap(options[:required])
|
45
|
+
self.messages_class_name.validates_presence_of self.messages_class_name.required
|
46
|
+
|
47
|
+
include ActsAsMessageable::Model::InstanceMethods
|
48
|
+
end
|
49
|
+
|
50
|
+
# Method recognize real object class
|
51
|
+
# @return [ActiveRecord::Base] class or relation object
|
52
|
+
def resolve_active_record_ancestor
|
53
|
+
self.reflect_on_association(:received_messages_relation).active_record
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
57
|
+
|
58
|
+
module InstanceMethods
|
59
|
+
# @return [ActiveRecord::Relation] all messages connected with user
|
60
|
+
def messages(trash = false)
|
61
|
+
result = self.class.messages_class_name.connected_with(self, trash)
|
62
|
+
result.relation_context = self
|
63
|
+
|
64
|
+
result
|
65
|
+
end
|
66
|
+
|
67
|
+
# @return [ActiveRecord::Relation] returns all messages from inbox
|
68
|
+
def received_messages
|
69
|
+
result = received_messages_relation.scoped.where(:recipient_delete => false)
|
70
|
+
result.relation_context = self
|
71
|
+
|
72
|
+
result
|
73
|
+
end
|
74
|
+
|
75
|
+
# @return [ActiveRecord::Relation] returns all messages from outbox
|
76
|
+
def sent_messages
|
77
|
+
result = sent_messages_relation.scoped.where(:sender_delete => false)
|
78
|
+
result.relation_context = self
|
79
|
+
|
80
|
+
result
|
81
|
+
end
|
82
|
+
|
83
|
+
# @return [ActiveRecord::Relation] returns all messages from trash
|
84
|
+
def deleted_messages
|
85
|
+
messages true
|
86
|
+
end
|
87
|
+
|
88
|
+
# Method sens message to another user
|
89
|
+
# @param [ActiveRecord::Base] to
|
90
|
+
# @param [String] topic
|
91
|
+
# @param [String] body
|
92
|
+
#
|
93
|
+
# @return [ActsAsMessageable::Message] the message object
|
94
|
+
def send_message(to, *args)
|
95
|
+
message_attributes = {}
|
96
|
+
|
97
|
+
case args.first
|
98
|
+
when String
|
99
|
+
self.class.messages_class_name.required.each_with_index do |attribute, index|
|
100
|
+
message_attributes[attribute] = args[index]
|
101
|
+
end
|
102
|
+
when Hash
|
103
|
+
message_attributes = args.first
|
104
|
+
end
|
105
|
+
|
106
|
+
message = self.class.messages_class_name.create message_attributes
|
107
|
+
message.received_messageable = to
|
108
|
+
message.sent_messageable = self
|
109
|
+
message.save
|
110
|
+
|
111
|
+
message
|
112
|
+
end
|
113
|
+
|
114
|
+
# Reply to given message
|
115
|
+
# @param [ActsAsMessageable::Message] message
|
116
|
+
# @param [String] topic
|
117
|
+
# @param [String] body
|
118
|
+
#
|
119
|
+
# @return [ActsAsMessageable::Message] a message that is a response to a given message
|
120
|
+
def reply_to(message, *args)
|
121
|
+
current_user = self
|
122
|
+
|
123
|
+
if message.participant?(current_user)
|
124
|
+
reply_message = send_message(message.real_receiver(current_user), *args)
|
125
|
+
reply_message.parent = message
|
126
|
+
reply_message.save
|
127
|
+
|
128
|
+
reply_message
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
# Mark message as deleted
|
133
|
+
def delete_message(message)
|
134
|
+
current_user = self
|
135
|
+
|
136
|
+
case current_user
|
137
|
+
when message.to
|
138
|
+
attribute = message.recipient_delete ? :recipient_permanent_delete : :recipient_delete
|
139
|
+
when message.from
|
140
|
+
attribute = message.sender_delete ? :sender_permanent_delete : :sender_delete
|
141
|
+
else
|
142
|
+
raise "#{current_user} can't delete this message"
|
143
|
+
end
|
144
|
+
|
145
|
+
message.update_attributes!(attribute => true)
|
146
|
+
end
|
147
|
+
|
148
|
+
# Mark message as restored
|
149
|
+
def restore_message(message)
|
150
|
+
current_user = self
|
151
|
+
|
152
|
+
case current_user
|
153
|
+
when message.to
|
154
|
+
attribute = :recipient_delete
|
155
|
+
when message.from
|
156
|
+
attribute = :sender_delete
|
157
|
+
else
|
158
|
+
raise "#{current_user} can't delete this message"
|
159
|
+
end
|
160
|
+
|
161
|
+
message.update_attributes!(attribute => false)
|
162
|
+
end
|
163
|
+
end
|
164
|
+
end
|
165
|
+
end
|