acts-as-messageable 0.4.11 → 0.5.0
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.
- checksums.yaml +4 -4
- data/.dockerignore +1 -0
- data/.rubocop.yml +19 -0
- data/.rubocop_todo.yml +33 -0
- data/.travis.yml +40 -4
- data/Appraisals +24 -11
- data/Dockerfile +13 -0
- data/Gemfile +11 -4
- data/Gemfile.lock +94 -63
- data/README.md +30 -12
- data/Rakefile +4 -0
- data/VERSION +1 -1
- data/acts-as-messageable.gemspec +62 -49
- data/docker-compose.yml +73 -0
- data/gemfiles/rails_3.2.gemfile +17 -10
- data/gemfiles/rails_4.2.gemfile +24 -0
- data/gemfiles/rails_5.2.gemfile +17 -10
- data/gemfiles/rails_6.0.gemfile +17 -10
- data/gemfiles/rails_master.gemfile +23 -0
- data/lib/acts-as-messageable.rb +2 -17
- data/lib/acts_as_messageable.rb +23 -0
- data/lib/{acts-as-messageable → acts_as_messageable}/message.rb +25 -8
- data/lib/{acts-as-messageable → acts_as_messageable}/model.rb +27 -30
- data/lib/{acts-as-messageable → acts_as_messageable}/rails3.rb +7 -5
- data/lib/{acts-as-messageable → acts_as_messageable}/rails4.rb +8 -4
- data/lib/acts_as_messageable/rails6.rb +31 -0
- data/lib/acts_as_messageable/railtie.rb +11 -0
- data/lib/{acts-as-messageable → acts_as_messageable}/relation.rb +4 -2
- data/lib/{acts-as-messageable → acts_as_messageable}/scopes.rb +16 -12
- data/lib/generators/{acts-as-messageable → acts_as_messageable}/migration/migration_generator.rb +16 -2
- data/lib/generators/{acts-as-messageable → acts_as_messageable}/migration/templates/migration.rb +3 -3
- data/lib/generators/acts_as_messageable/migration/templates/migration_indexes.rb +11 -0
- data/lib/generators/acts_as_messageable/migration/templates/migration_opened_as_datetime.rb +15 -0
- data/lib/generators/{acts-as-messageable → acts_as_messageable}/migration/templates/migration_permanent.rb +1 -1
- data/spec/{acts-as-messageable_spec.rb → acts_as_messageable_spec.rb} +77 -5
- data/spec/{custom-class_spec.rb → custom_class_spec.rb} +14 -5
- data/spec/{custom-required_spec.rb → custom_required_spec.rb} +3 -1
- data/spec/{group-messages_spec.rb → group_messages_spec.rb} +4 -2
- data/spec/migrations_spec.rb +75 -0
- data/spec/spec_helper.rb +30 -37
- data/spec/support/admin.rb +2 -0
- data/spec/support/custom_message.rb +5 -0
- data/spec/support/custom_message_uuid.rb +5 -0
- data/spec/support/custom_search_user.rb +5 -0
- data/spec/support/men.rb +6 -0
- data/spec/support/send_message.rb +2 -0
- data/spec/support/table_schema.rb +35 -0
- data/spec/support/user.rb +2 -3
- data/spec/support/uuid_user.rb +6 -0
- metadata +113 -31
- data/gemfiles/rails_3.2.gemfile.lock +0 -153
- data/gemfiles/rails_4.2.11.gemfile +0 -16
- data/gemfiles/rails_4.2.11.gemfile.lock +0 -157
- data/gemfiles/rails_5.2.gemfile.lock +0 -155
- data/gemfiles/rails_6.0.gemfile.lock +0 -155
- data/lib/acts-as-messageable/railtie.rb +0 -13
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# This file was generated by Appraisal
|
4
|
+
|
5
|
+
source 'http://rubygems.org'
|
6
|
+
|
7
|
+
gem 'activerecord', git: 'https://github.com/rails/rails.git'
|
8
|
+
gem 'activesupport', git: 'https://github.com/rails/rails.git'
|
9
|
+
gem 'ancestry'
|
10
|
+
gem 'railties', git: 'https://github.com/rails/rails.git'
|
11
|
+
|
12
|
+
group :development do
|
13
|
+
gem 'appraisal'
|
14
|
+
gem 'coveralls', require: false
|
15
|
+
gem 'jeweler'
|
16
|
+
gem 'pg'
|
17
|
+
gem 'pry'
|
18
|
+
gem 'rspec'
|
19
|
+
gem 'rubocop', require: false
|
20
|
+
gem 'sqlite3'
|
21
|
+
gem 'timecop'
|
22
|
+
gem 'yard'
|
23
|
+
end
|
data/lib/acts-as-messageable.rb
CHANGED
@@ -1,18 +1,3 @@
|
|
1
|
-
|
2
|
-
autoload :Model, 'acts-as-messageable/model'
|
3
|
-
autoload :Scopes, 'acts-as-messageable/scopes'
|
4
|
-
autoload :Message, 'acts-as-messageable/message'
|
5
|
-
autoload :Relation, 'acts-as-messageable/relation'
|
6
|
-
autoload :Rails3, 'acts-as-messageable/rails3'
|
7
|
-
autoload :Rails4, 'acts-as-messageable/rails4'
|
1
|
+
# frozen_string_literal: true
|
8
2
|
|
9
|
-
|
10
|
-
if Rails::VERSION::MAJOR >= 4
|
11
|
-
Rails4
|
12
|
-
else
|
13
|
-
Rails3
|
14
|
-
end
|
15
|
-
end
|
16
|
-
end
|
17
|
-
|
18
|
-
require 'acts-as-messageable/railtie'
|
3
|
+
require 'acts_as_messageable'
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ActsAsMessageable
|
4
|
+
autoload :Model, 'acts_as_messageable/model'
|
5
|
+
autoload :Scopes, 'acts_as_messageable/scopes'
|
6
|
+
autoload :Message, 'acts_as_messageable/message'
|
7
|
+
autoload :Relation, 'acts_as_messageable/relation'
|
8
|
+
autoload :Rails3, 'acts_as_messageable/rails3'
|
9
|
+
autoload :Rails4, 'acts_as_messageable/rails4'
|
10
|
+
autoload :Rails6, 'acts_as_messageable/rails6'
|
11
|
+
|
12
|
+
def self.rails_api
|
13
|
+
if Rails::VERSION::MAJOR >= 6
|
14
|
+
Rails6
|
15
|
+
elsif Rails::VERSION::MAJOR >= 4
|
16
|
+
Rails4
|
17
|
+
else
|
18
|
+
Rails3
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
require 'acts_as_messageable/railtie'
|
@@ -1,35 +1,52 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'ancestry'
|
2
4
|
|
3
5
|
module ActsAsMessageable
|
4
6
|
class Message < ::ActiveRecord::Base
|
5
7
|
include ActsAsMessageable::Scopes
|
6
8
|
|
9
|
+
has_ancestry
|
10
|
+
|
7
11
|
belongs_to :received_messageable, polymorphic: true
|
8
|
-
belongs_to :sent_messageable,
|
12
|
+
belongs_to :sent_messageable, polymorphic: true
|
9
13
|
|
10
|
-
attr_accessor
|
11
|
-
cattr_accessor :required
|
14
|
+
attr_accessor :removed, :restored
|
12
15
|
|
16
|
+
cattr_accessor :required
|
17
|
+
|
18
|
+
ActsAsMessageable.rails_api.new(self).attr_accessible(
|
19
|
+
:topic, :body, :opened, :opened_at, :recipient_permanent_delete,
|
20
|
+
:recipient_delete, :sender_permanent_delete, :sender_delete
|
21
|
+
)
|
13
22
|
ActsAsMessageable.rails_api.new(self).default_scope('created_at desc')
|
14
23
|
|
15
24
|
def open?
|
16
25
|
opened?
|
17
26
|
end
|
18
27
|
|
28
|
+
def opened?
|
29
|
+
opened_at.present? || super
|
30
|
+
end
|
31
|
+
|
19
32
|
def open
|
20
|
-
update_attributes!(
|
33
|
+
ActsAsMessageable.rails_api.new(self).update_attributes!(opened_at: DateTime.now)
|
34
|
+
ActsAsMessageable.rails_api.new(self).update_attributes!(opened: true)
|
21
35
|
end
|
36
|
+
|
22
37
|
alias mark_as_read open
|
23
|
-
alias read
|
38
|
+
alias read open
|
24
39
|
|
25
40
|
def close
|
26
|
-
update_attributes!(
|
41
|
+
ActsAsMessageable.rails_api.new(self).update_attributes!(opened_at: nil)
|
42
|
+
ActsAsMessageable.rails_api.new(self).update_attributes!(opened: false)
|
27
43
|
end
|
44
|
+
|
28
45
|
alias mark_as_unread close
|
29
|
-
alias unread
|
46
|
+
alias unread close
|
30
47
|
|
31
48
|
alias from sent_messageable
|
32
|
-
alias to
|
49
|
+
alias to received_messageable
|
33
50
|
|
34
51
|
def real_receiver(user)
|
35
52
|
user == from ? to : from
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module ActsAsMessageable
|
2
4
|
module Model
|
3
5
|
def self.included(base)
|
@@ -5,49 +7,46 @@ module ActsAsMessageable
|
|
5
7
|
end
|
6
8
|
|
7
9
|
module ClassMethods
|
8
|
-
mattr_accessor :messages_class_name, :group_messages
|
9
|
-
|
10
10
|
# Method make ActiveRecord::Base object messageable
|
11
11
|
# @param [Symbol] :table_name - table name for messages
|
12
12
|
# @param [String] :class_name - message class name
|
13
13
|
# @param [Array, Symbol] :required - required fields in message
|
14
14
|
# @param [Symbol] :dependent - dependent option from ActiveRecord has_many method
|
15
|
+
# @param [Symbol] :search_scope - name of a scope for a full text search
|
15
16
|
def acts_as_messageable(options = {})
|
16
17
|
default_options = {
|
17
18
|
table_name: 'messages',
|
18
19
|
class_name: 'ActsAsMessageable::Message',
|
19
20
|
required: %i[topic body],
|
20
21
|
dependent: :nullify,
|
21
|
-
group_messages: false
|
22
|
+
group_messages: false,
|
23
|
+
search_scope: :search
|
22
24
|
}
|
23
25
|
options = default_options.merge(options)
|
24
26
|
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
27
|
+
mattr_accessor(:messages_class_name, :group_messages)
|
28
|
+
|
29
|
+
has_many :received_messages_relation,
|
30
|
+
as: :received_messageable,
|
31
|
+
class_name: options[:class_name],
|
32
|
+
dependent: options[:dependent]
|
33
|
+
has_many :sent_messages_relation,
|
34
|
+
as: :sent_messageable,
|
35
|
+
class_name: options[:class_name],
|
36
|
+
dependent: options[:dependent]
|
33
37
|
|
34
38
|
self.messages_class_name = options[:class_name].constantize
|
35
39
|
messages_class_name.has_ancestry
|
36
40
|
|
37
|
-
|
38
|
-
|
39
|
-
messages_class_name.initialize_scopes
|
40
|
-
else
|
41
|
-
messages_class_name.set_table_name(options[:table_name])
|
42
|
-
ActiveSupport::Deprecation.warn("Calling set_table_name is deprecated. Please use `self.table_name = 'the_name'` instead.")
|
43
|
-
end
|
41
|
+
messages_class_name.table_name = options[:table_name]
|
42
|
+
messages_class_name.initialize_scopes(options[:search_scope])
|
44
43
|
|
45
44
|
messages_class_name.required = Array.wrap(options[:required])
|
46
45
|
messages_class_name.validates_presence_of messages_class_name.required
|
47
46
|
self.group_messages = options[:group_messages]
|
48
47
|
|
49
48
|
include ActsAsMessageable::Model::InstanceMethods
|
50
|
-
|
49
|
+
end
|
51
50
|
|
52
51
|
# Method recognize real object class
|
53
52
|
# @return [ActiveRecord::Base] class or relation object
|
@@ -122,9 +121,7 @@ module ActsAsMessageable
|
|
122
121
|
#
|
123
122
|
# @return [ActsAsMessageable::Message] the message object
|
124
123
|
def send_message!(to, *args)
|
125
|
-
send_message(to, *args).tap
|
126
|
-
message.save!
|
127
|
-
end
|
124
|
+
send_message(to, *args).tap(&:save!)
|
128
125
|
end
|
129
126
|
|
130
127
|
# Reply to given message
|
@@ -136,13 +133,13 @@ module ActsAsMessageable
|
|
136
133
|
def reply_to(message, *args)
|
137
134
|
current_user = self
|
138
135
|
|
139
|
-
|
140
|
-
reply_message = send_message(message.real_receiver(current_user), *args)
|
141
|
-
reply_message.parent = message
|
142
|
-
reply_message.save
|
136
|
+
return unless message.participant?(current_user)
|
143
137
|
|
144
|
-
|
145
|
-
|
138
|
+
reply_message = send_message(message.real_receiver(current_user), *args)
|
139
|
+
reply_message.parent = message
|
140
|
+
reply_message.save
|
141
|
+
|
142
|
+
reply_message
|
146
143
|
end
|
147
144
|
|
148
145
|
# Mark message as deleted
|
@@ -158,7 +155,7 @@ module ActsAsMessageable
|
|
158
155
|
raise "#{current_user} can't delete this message"
|
159
156
|
end
|
160
157
|
|
161
|
-
message.update_attributes!(attribute => true)
|
158
|
+
ActsAsMessageable.rails_api.new(message).update_attributes!(attribute => true)
|
162
159
|
end
|
163
160
|
|
164
161
|
# Mark message as restored
|
@@ -174,7 +171,7 @@ module ActsAsMessageable
|
|
174
171
|
raise "#{current_user} can't restore this message"
|
175
172
|
end
|
176
173
|
|
177
|
-
message.update_attributes!(attribute => false)
|
174
|
+
ActsAsMessageable.rails_api.new(message).update_attributes!(attribute => false)
|
178
175
|
end
|
179
176
|
end
|
180
177
|
end
|
@@ -1,19 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module ActsAsMessageable
|
2
4
|
class Rails3
|
3
5
|
def initialize(subject)
|
4
6
|
@subject = subject
|
5
7
|
end
|
6
8
|
|
7
|
-
def attr_accessible(*args)
|
8
|
-
@subject.attr_accessible(*args)
|
9
|
-
end
|
10
|
-
|
11
9
|
def default_scope(order_by)
|
12
10
|
@subject.send(:default_scope, order(order_by))
|
13
11
|
end
|
14
12
|
|
15
13
|
def method_missing(name, *args)
|
16
|
-
@subject.send(name, *args)
|
14
|
+
@subject.send(name, *args) || super
|
15
|
+
end
|
16
|
+
|
17
|
+
def respond_to_missing?(method_name, include_private = false)
|
18
|
+
method_name.to_s == 'default_scope' || super
|
17
19
|
end
|
18
20
|
end
|
19
21
|
end
|
@@ -1,12 +1,12 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module ActsAsMessageable
|
2
4
|
class Rails4
|
3
5
|
def initialize(subject)
|
4
6
|
@subject = subject
|
5
7
|
end
|
6
8
|
|
7
|
-
def attr_accessible(*
|
8
|
-
@subject.attr_accessible(*args) if defined?(ProtectedAttributes)
|
9
|
-
end
|
9
|
+
def attr_accessible(*); end
|
10
10
|
|
11
11
|
def default_scope(order_by)
|
12
12
|
@subject.send(:default_scope) { order(order_by) }
|
@@ -17,7 +17,11 @@ module ActsAsMessageable
|
|
17
17
|
end
|
18
18
|
|
19
19
|
def method_missing(name, *args)
|
20
|
-
@subject.send(name, *args)
|
20
|
+
@subject.send(name, *args) || super
|
21
|
+
end
|
22
|
+
|
23
|
+
def respond_to_missing?(method_name, include_private = false)
|
24
|
+
%w[default_scope scoped attr_accessible].include?(method_name) || super
|
21
25
|
end
|
22
26
|
end
|
23
27
|
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ActsAsMessageable
|
4
|
+
class Rails6
|
5
|
+
def initialize(subject)
|
6
|
+
@subject = subject
|
7
|
+
end
|
8
|
+
|
9
|
+
def attr_accessible(*); end
|
10
|
+
|
11
|
+
def default_scope(order_by)
|
12
|
+
@subject.send(:default_scope) { order(order_by) }
|
13
|
+
end
|
14
|
+
|
15
|
+
def scoped
|
16
|
+
@subject.scope
|
17
|
+
end
|
18
|
+
|
19
|
+
def update_attributes!(*args)
|
20
|
+
@subject.update!(*args)
|
21
|
+
end
|
22
|
+
|
23
|
+
def method_missing(name, *args)
|
24
|
+
@subject.send(name, *args) || super
|
25
|
+
end
|
26
|
+
|
27
|
+
def respond_to_missing?(method_name, include_private = false)
|
28
|
+
%w[attr_accessible default_scope scoped update_attributes!].include?(method_name) || super
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'active_record/railtie'
|
4
|
+
|
5
|
+
module ActsAsMessageable
|
6
|
+
class Railtie < Rails::Railtie
|
7
|
+
ActiveRecord::Base.include ActsAsMessageable::Model if defined?(ActiveRecord::Base)
|
8
|
+
|
9
|
+
ActiveRecord::Relation.include ActsAsMessageable::Relation if defined?(ActiveRecord::Relation)
|
10
|
+
end
|
11
|
+
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module ActsAsMessageable
|
2
4
|
module Relation
|
3
5
|
attr_accessor :relation_context
|
@@ -5,8 +7,8 @@ module ActsAsMessageable
|
|
5
7
|
def process(context = relation_context)
|
6
8
|
each do |message|
|
7
9
|
yield(message) if block_given?
|
8
|
-
context.delete_message(message)
|
9
|
-
context.restore_message(message)
|
10
|
+
context.delete_message(message) if message.removed
|
11
|
+
context.restore_message(message) if message.restored
|
10
12
|
end
|
11
13
|
end
|
12
14
|
|
@@ -1,19 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'active_support/concern'
|
2
4
|
|
3
5
|
module ActsAsMessageable
|
4
6
|
module Scopes
|
5
7
|
extend ActiveSupport::Concern
|
6
8
|
|
7
|
-
included do
|
8
|
-
initialize_scopes
|
9
|
-
end
|
10
|
-
|
11
9
|
module ClassMethods
|
12
|
-
def initialize_scopes
|
13
|
-
scope :are_from,
|
14
|
-
|
15
|
-
|
16
|
-
scope :
|
10
|
+
def initialize_scopes(search_scope)
|
11
|
+
scope :are_from, lambda { |*args|
|
12
|
+
where(sent_messageable_id: args.first, sent_messageable_type: args.first.class.name)
|
13
|
+
}
|
14
|
+
scope :are_to, lambda { |*args|
|
15
|
+
where(received_messageable_id: args.first, received_messageable_type: args.first.class.name)
|
16
|
+
}
|
17
|
+
scope search_scope, lambda { |*args|
|
18
|
+
where('body like :search_txt or topic like :search_txt', search_txt: "%#{args.first}%")
|
19
|
+
}
|
20
|
+
scope :connected_with, lambda { |*args|
|
17
21
|
where("(sent_messageable_type = :sent_type and
|
18
22
|
sent_messageable_id = :sent_id and
|
19
23
|
sender_delete = :s_delete and sender_permanent_delete = :s_perm_delete) or
|
@@ -29,9 +33,9 @@ module ActsAsMessageable
|
|
29
33
|
r_perm_delete: false,
|
30
34
|
s_perm_delete: false)
|
31
35
|
}
|
32
|
-
scope :readed,
|
33
|
-
scope :unreaded,
|
34
|
-
scope :deleted,
|
36
|
+
scope :readed, -> { where('opened_at is not null OR opened = ?', true) }
|
37
|
+
scope :unreaded, -> { where('opened_at is null OR opened = ?', false) }
|
38
|
+
scope :deleted, -> { where(recipient_delete: true, sender_delete: true) }
|
35
39
|
end
|
36
40
|
end
|
37
41
|
end
|
data/lib/generators/{acts-as-messageable → acts_as_messageable}/migration/migration_generator.rb
RENAMED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'rails/generators/migration'
|
2
4
|
require 'rails/generators/active_record'
|
3
5
|
|
@@ -5,10 +7,11 @@ module ActsAsMessageable
|
|
5
7
|
class MigrationGenerator < Rails::Generators::Base
|
6
8
|
include Rails::Generators::Migration
|
7
9
|
|
8
|
-
namespace '
|
10
|
+
namespace 'acts_as_messageable:migration'
|
9
11
|
|
10
12
|
source_root File.join(File.dirname(__FILE__), 'templates')
|
11
13
|
argument :table_name, type: :string, default: 'messages'
|
14
|
+
class_option :uuid, type: :boolean, default: false
|
12
15
|
|
13
16
|
def self.next_migration_number(dirname)
|
14
17
|
ActiveRecord::Generators::Base.next_migration_number(dirname)
|
@@ -21,7 +24,18 @@ module ActsAsMessageable
|
|
21
24
|
nil
|
22
25
|
end
|
23
26
|
begin
|
24
|
-
migration_template 'migration_permanent.rb',
|
27
|
+
migration_template 'migration_permanent.rb',
|
28
|
+
'db/migrate/add_recipient_permanent_delete_and_sender_permanent_delete_to_messages.rb'
|
29
|
+
rescue StandardError
|
30
|
+
nil
|
31
|
+
end
|
32
|
+
begin
|
33
|
+
migration_template 'migration_opened_as_datetime.rb', 'db/migrate/add_opened_at_to_messages.rb'
|
34
|
+
rescue StandardError
|
35
|
+
nil
|
36
|
+
end
|
37
|
+
begin
|
38
|
+
migration_template 'migration_indexes.rb', 'db/migrate/add_indexes_to_messages.rb'
|
25
39
|
rescue StandardError
|
26
40
|
nil
|
27
41
|
end
|