social_man 0.1.0 → 0.2.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/app/models/action.rb +1 -1
- data/lib/generators/social_man_generator.rb +41 -0
- data/lib/generators/templates/README +8 -0
- data/lib/generators/templates/initializer.rb +4 -0
- data/lib/generators/templates/migration.rb +12 -0
- data/lib/generators/templates/model.rb +3 -0
- data/lib/social_man.rb +4 -0
- data/lib/social_man/action_model.rb +6 -2
- data/lib/social_man/action_object.rb +71 -5
- data/lib/social_man/action_subject.rb +71 -8
- data/lib/social_man/action_thesaurus.rb +78 -0
- data/lib/social_man/configure.rb +30 -0
- data/lib/social_man/version.rb +1 -1
- metadata +25 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: bc565ae17296e2e1570eea93006c687b9eb98a46ecfb7cfa34c590de703e09f8
|
4
|
+
data.tar.gz: f20b035053e73233c20e151bb9a1f84f44e377eccace08d66cbe662f28acb70c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 99dc914979f634d4cb22edec6fb2fbfe13ad3b87d8d032c62c0f5d60528753dbcdf6e7ec5050bccb95bdec3962252ad4a83ef138dfcf053795f7f2a6bbe4e7b1
|
7
|
+
data.tar.gz: 3db8524fd964a11eb06b60688ef7426dee3973bedcc56fddb8a2b3dbeb6a036c129a1020312d3453e8c026be8df6defc4989cf240341ff89f1bad8c7fb1ebf36
|
data/app/models/action.rb
CHANGED
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'rails/generators'
|
2
|
+
require 'rails/generators/migration'
|
3
|
+
|
4
|
+
class SocialManGenerator < Rails::Generators::Base
|
5
|
+
|
6
|
+
include Rails::Generators::Migration
|
7
|
+
|
8
|
+
def self.source_root
|
9
|
+
@source_root ||= File.join(File.dirname(__FILE__), 'templates')
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.next_migration_number(dir)
|
13
|
+
Time.now.utc.strftime("%Y%m%d%H%M%S")
|
14
|
+
end
|
15
|
+
|
16
|
+
def create_migration_file
|
17
|
+
migration_template 'migration.rb', 'db/migrate/social_man_create_actions.rb',
|
18
|
+
migration_version: migration_version
|
19
|
+
end
|
20
|
+
|
21
|
+
def create_model
|
22
|
+
template "model.rb", File.join('app/models', "actions.rb")
|
23
|
+
end
|
24
|
+
|
25
|
+
def copy_initializer_file
|
26
|
+
template "initializer.rb", "config/initializers/social_man.rb"
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
def rails5?
|
32
|
+
Rails.version.start_with? '5'
|
33
|
+
end
|
34
|
+
|
35
|
+
def migration_version
|
36
|
+
if rails5?
|
37
|
+
"[#{Rails::VERSION::MAJOR}.#{Rails::VERSION::MINOR}]"
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
@@ -0,0 +1,8 @@
|
|
1
|
+
Now, you just have to run the migration using rake command:
|
2
|
+
|
3
|
+
rake db:migrate
|
4
|
+
|
5
|
+
and you will be able to add the acts_as_action_subject or acts_as_action_object
|
6
|
+
method inside models.
|
7
|
+
|
8
|
+
===============================================================================
|
@@ -0,0 +1,12 @@
|
|
1
|
+
class SocialManCreateActions < ActiveRecord::Migration<%= migration_version %>
|
2
|
+
def change
|
3
|
+
create_table :actions do |t|
|
4
|
+
t.references :action_subject, polymorphic: true
|
5
|
+
t.string :action_type
|
6
|
+
t.string :action_options
|
7
|
+
t.references :action_object, polymorphic: true
|
8
|
+
|
9
|
+
t.timestamps
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
data/lib/social_man.rb
CHANGED
@@ -1,8 +1,12 @@
|
|
1
1
|
require "social_man/version"
|
2
2
|
require "social_man/engine"
|
3
3
|
require 'social_man/railtie' if defined?(Rails) && Rails::VERSION::MAJOR >= 3
|
4
|
+
require 'social_man/configure'
|
5
|
+
require 'social_man/action_thesaurus'
|
4
6
|
|
5
7
|
module SocialMan
|
8
|
+
extend Configure
|
9
|
+
|
6
10
|
autoload :ActionSubject, 'social_man/action_subject'
|
7
11
|
autoload :ActionObject, 'social_man/action_object'
|
8
12
|
autoload :ActionModel, 'social_man/action_model'
|
@@ -1,11 +1,15 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
|
3
|
+
#
|
4
|
+
# Like, Star
|
5
|
+
|
2
6
|
module SocialMan
|
3
7
|
module ActionModel
|
4
8
|
extend ActiveSupport::Concern
|
5
9
|
|
6
10
|
included do
|
7
|
-
belongs_to :
|
8
|
-
belongs_to :
|
11
|
+
belongs_to :action_subject, polymorphic: true
|
12
|
+
belongs_to :action_object, polymorphic: true
|
9
13
|
end
|
10
14
|
end
|
11
15
|
end
|
@@ -7,7 +7,7 @@ module SocialMan
|
|
7
7
|
|
8
8
|
module ClassMethods
|
9
9
|
def acts_as_action_object
|
10
|
-
has_many :passive_actions, class_name: 'Action',
|
10
|
+
has_many :passive_actions, class_name: 'Action', as: :action_object,
|
11
11
|
dependent: :destroy
|
12
12
|
|
13
13
|
include SocialMan::ActionObject::InstanceMethods
|
@@ -15,13 +15,79 @@ module SocialMan
|
|
15
15
|
end
|
16
16
|
|
17
17
|
module InstanceMethods
|
18
|
-
def
|
19
|
-
Action.create
|
18
|
+
def taken_action_by(action_subject, action_type = 'Action')
|
19
|
+
Action.create action_type: action_type, action_subject: action_subject, action_object: self
|
20
20
|
end
|
21
21
|
|
22
|
-
def passive_to?(
|
23
|
-
Action.exists?
|
22
|
+
def passive_to?(action_subject, action_type = 'Action')
|
23
|
+
Action.exists? action_type: action_type, action_subject: action_subject, action_object: self
|
24
24
|
end
|
25
|
+
|
26
|
+
def undo_action_by(action_subject, action_type = 'Action')
|
27
|
+
Action.where(action_type: action_type, action_subject: action_subject, action_object: self)
|
28
|
+
.destroy_all
|
29
|
+
end
|
30
|
+
|
31
|
+
SocialMan.actions.each do |action|
|
32
|
+
define_method action.passive_action do |action_subject|
|
33
|
+
taken_action_by action_subject, action.type
|
34
|
+
end
|
35
|
+
|
36
|
+
# define_method "#{action.passive_action}!" do |action_subject|
|
37
|
+
# send action.action, action_subject || raise Exception
|
38
|
+
# end
|
39
|
+
|
40
|
+
define_method "#{action.passive_action}?" do |action_subject|
|
41
|
+
passive_to? action_subject, action.type
|
42
|
+
end
|
43
|
+
|
44
|
+
define_method action.passive_undo do |action_subject|
|
45
|
+
undo_action_by action_subject, action.type
|
46
|
+
end
|
47
|
+
|
48
|
+
# define_method "#{action.passive_undo}!" do |action_subject|
|
49
|
+
# send action.passive_undo, action_subject || raise Exception
|
50
|
+
# end
|
51
|
+
|
52
|
+
define_method "#{action.passive_undo}?" do |action_subject|
|
53
|
+
!passive_to? action_subject, action.type
|
54
|
+
end
|
55
|
+
|
56
|
+
# todo
|
57
|
+
# define_method action.all_subjects do |action_subject|
|
58
|
+
# ids = active_actions.pluck(:action_subject_id)
|
59
|
+
# subject_class.where id: ids
|
60
|
+
# end
|
61
|
+
end
|
62
|
+
|
63
|
+
# subjects_prefix
|
64
|
+
def method_missing(method_name, *args)
|
65
|
+
action_type, subject_class = find_subject_class method_name.to_s
|
66
|
+
|
67
|
+
if subject_class.nil?
|
68
|
+
super
|
69
|
+
else
|
70
|
+
ids = passive_actions.where(action_type: action_type).pluck(:action_subject_id)
|
71
|
+
subject_class.where id: ids
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
private
|
76
|
+
|
77
|
+
def find_subject_class(method_name)
|
78
|
+
action_type = ''
|
79
|
+
subject_type = nil
|
80
|
+
SocialMan.actions.each do |action|
|
81
|
+
if method_name.start_with? action.subjects_prefix
|
82
|
+
action_type = action.type
|
83
|
+
subject_name = method_name.remove action.subjects_prefix
|
84
|
+
subject_type = subject_name.singularize.camelize unless subject_name.blank?
|
85
|
+
break
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
[action_type, subject_type&.constantize]
|
90
|
+
end
|
25
91
|
end
|
26
92
|
|
27
93
|
end
|
@@ -7,24 +7,87 @@ module SocialMan
|
|
7
7
|
|
8
8
|
module ClassMethods
|
9
9
|
def acts_as_action_subject
|
10
|
-
has_many :active_actions, class_name: 'Action',
|
10
|
+
has_many :active_actions, class_name: 'Action', as: :action_subject,
|
11
11
|
dependent: :destroy
|
12
|
-
# has_many :action_objects, class_name: 'Action',
|
13
|
-
# source: :subject,
|
14
|
-
# through: :active_actions
|
15
12
|
|
16
13
|
include SocialMan::ActionSubject::InstanceMethods
|
17
14
|
end
|
18
15
|
end
|
19
16
|
|
20
17
|
module InstanceMethods
|
21
|
-
def take_action_on(
|
22
|
-
Action.create
|
18
|
+
def take_action_on(action_object, action_type = 'Action')
|
19
|
+
Action.create action_type: action_type, action_subject: self, action_object: action_object
|
23
20
|
end
|
24
21
|
|
25
|
-
def active_to?(
|
26
|
-
Action.exists?
|
22
|
+
def active_to?(action_object, action_type = 'Action')
|
23
|
+
Action.exists? action_type: action_type, action_subject: self, action_object: action_object
|
27
24
|
end
|
25
|
+
|
26
|
+
def undo_action_on(action_object, action_type = 'Action')
|
27
|
+
Action.where(action_type: action_type, action_subject: self, action_object: action_object)
|
28
|
+
.destroy_all
|
29
|
+
end
|
30
|
+
|
31
|
+
SocialMan.actions.each do |action|
|
32
|
+
define_method action.action do |action_object|
|
33
|
+
take_action_on action_object, action.type
|
34
|
+
end
|
35
|
+
|
36
|
+
# define_method "#{action.action}!" do |action_object|
|
37
|
+
# send action.action, action_object || raise Exception
|
38
|
+
# end
|
39
|
+
|
40
|
+
define_method "#{action.action}?" do |action_object|
|
41
|
+
active_to? action_object, action.type
|
42
|
+
end
|
43
|
+
|
44
|
+
define_method action.undo do |action_object|
|
45
|
+
undo_action_on action_object, action.type
|
46
|
+
end
|
47
|
+
|
48
|
+
# define_method "#{action.undo}!" do |action_object|
|
49
|
+
# send action.undo, action_object || raise Exception
|
50
|
+
# end
|
51
|
+
|
52
|
+
define_method "#{action.undo}?" do |action_object|
|
53
|
+
!active_to? action_object, action.type
|
54
|
+
end
|
55
|
+
|
56
|
+
# todo
|
57
|
+
# define_method action.all_subjects do |action_object|
|
58
|
+
# ids = active_actions.pluck(:action_object_id)
|
59
|
+
# object_class.where id: ids
|
60
|
+
# end
|
61
|
+
end
|
62
|
+
|
63
|
+
# objects_prefix
|
64
|
+
def method_missing(method_name, *args)
|
65
|
+
action_type, object_class = find_object_class method_name.to_s
|
66
|
+
|
67
|
+
if object_class.nil?
|
68
|
+
super
|
69
|
+
else
|
70
|
+
ids = active_actions.where(action_type: action_type).pluck(:action_object_id)
|
71
|
+
object_class.where id: ids
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
private
|
76
|
+
|
77
|
+
def find_object_class(method_name)
|
78
|
+
action_type = ''
|
79
|
+
object_type = nil
|
80
|
+
SocialMan.actions.each do |action|
|
81
|
+
if method_name.start_with? action.objects_prefix
|
82
|
+
action_type = action.type
|
83
|
+
object_name = method_name.remove action.objects_prefix
|
84
|
+
object_type = object_name.singularize.camelize unless object_name.blank?
|
85
|
+
break
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
[action_type, object_type&.constantize]
|
90
|
+
end
|
28
91
|
end
|
29
92
|
|
30
93
|
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# :like symbole, action
|
4
|
+
# Like type
|
5
|
+
# like do action (present_tense) / like! like?
|
6
|
+
# unlike undo action (un-) / unlike! unlike?
|
7
|
+
# liked_by passive do action (-ed_by) / liked_by! liked_by?
|
8
|
+
# unliked_by passive undo action (un-*-ed_by) / unliked_by! unliked_by?
|
9
|
+
# liking_XX subjects_prefix (progressive tense -ing_) (liking_user, liking_users)
|
10
|
+
# liked_XX objects_prefix (past_tense -ed_) (liked_article, liked_articles)
|
11
|
+
# likers all subjects (-ers) liker, all likers
|
12
|
+
# likables all objects (-ables) likable, all likables
|
13
|
+
|
14
|
+
module SocialMan
|
15
|
+
class ActionThesaurus
|
16
|
+
attr_reader :name, :type, :action, :undo, :passive_action, :passive_undo,
|
17
|
+
:subjects_prefix, :objects_prefix, :all_subjects, :all_objects
|
18
|
+
|
19
|
+
def initialize(action_name, options={})
|
20
|
+
@name = action_name.to_sym
|
21
|
+
name = action_name.to_s
|
22
|
+
@type = options_or_thesaurus(options, :type) || name.camelize
|
23
|
+
@action = options_or_thesaurus(options, :action) || name
|
24
|
+
@undo = options_or_thesaurus(options, :undo) || 'un' + name
|
25
|
+
@passive_action = options_or_thesaurus(options, :passive_action) || name + 'ed_by'
|
26
|
+
@passive_undo = options_or_thesaurus(options, :passive_undo) || 'un' + name + + 'ed_by'
|
27
|
+
@subjects_prefix = options_or_thesaurus(options, :subjects_prefix) || name + 'ing_'
|
28
|
+
@objects_prefix = options_or_thesaurus(options, :objects_prefix) || name + 'ed_'
|
29
|
+
@all_subjects = options_or_thesaurus(options, :all_subjects) || name + 'ers'
|
30
|
+
@all_objects = options_or_thesaurus(options, :all_objects) || name + 'ables'
|
31
|
+
end
|
32
|
+
|
33
|
+
private
|
34
|
+
|
35
|
+
def options_or_thesaurus(options, key)
|
36
|
+
options[key].presence || fetch_thesaurus(@name, key)
|
37
|
+
end
|
38
|
+
|
39
|
+
def fetch_thesaurus(action_name, key)
|
40
|
+
action = ActionThesaurus.thesaurus[action_name]
|
41
|
+
action.nil? ? nil : action[key]
|
42
|
+
end
|
43
|
+
|
44
|
+
class << self
|
45
|
+
def thesaurus
|
46
|
+
@@thesaurus ||= init_thesaurus
|
47
|
+
end
|
48
|
+
|
49
|
+
def init_thesaurus
|
50
|
+
thesaurus_array = [
|
51
|
+
%w(like unlike liked_by unliked_by liking liked liker likeable),
|
52
|
+
%w(star unstar starred_by unstarred_by starring starred starrer starable),
|
53
|
+
%w(block unblock blocked_by unblocked_by blocking blocked blockers blockable),
|
54
|
+
%w(follow unfollow followed_by unfollowed_by following followed follower followee),
|
55
|
+
%w(vote unvote voted_by unvoted_by voting voted voter votable)
|
56
|
+
]
|
57
|
+
|
58
|
+
thesaurus = {}
|
59
|
+
thesaurus_array.each do |line|
|
60
|
+
thesaurus[line[0].to_sym] = {
|
61
|
+
name: line[0].to_sym,
|
62
|
+
type: line[0].camelize,
|
63
|
+
action: line[0],
|
64
|
+
undo: line[1],
|
65
|
+
passive_action: line[2],
|
66
|
+
passive_undo: line[3],
|
67
|
+
subjects_prefix: line[4] + '_',
|
68
|
+
objects_prefix: line[5] + '_',
|
69
|
+
all_subjects: line[6].pluralize,
|
70
|
+
all_objects: line[7].pluralize
|
71
|
+
}
|
72
|
+
end
|
73
|
+
|
74
|
+
thesaurus
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module SocialMan
|
2
|
+
module Configure
|
3
|
+
# :like symbole
|
4
|
+
# Like type
|
5
|
+
# like action (present_tense) / like! like?
|
6
|
+
# unlike reverse action (un-) / unlike! unlike?
|
7
|
+
# liking_XX subjects (progressive tense -ing) (liking_users)
|
8
|
+
# liked_XX objects (past_tense -ed) (liked_articles)
|
9
|
+
# liker all subjects (-er)
|
10
|
+
# likable all objects (-able)
|
11
|
+
|
12
|
+
@@actions = []
|
13
|
+
|
14
|
+
def configure
|
15
|
+
yield self if block_given?
|
16
|
+
end
|
17
|
+
|
18
|
+
def actions=(actions)
|
19
|
+
actions.each { |action| @@actions << SocialMan::ActionThesaurus.new(action) }
|
20
|
+
end
|
21
|
+
|
22
|
+
def actions
|
23
|
+
@@actions
|
24
|
+
end
|
25
|
+
|
26
|
+
def define_action(action, **options)
|
27
|
+
@@actions << SocialMan::ActionThesaurus.new(action, options)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
data/lib/social_man/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: social_man
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- John Hu
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-09-
|
11
|
+
date: 2018-09-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -16,14 +16,14 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: 5.
|
19
|
+
version: '5.0'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: 5.
|
26
|
+
version: '5.0'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: sqlite3
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -80,6 +80,20 @@ dependencies:
|
|
80
80
|
- - ">="
|
81
81
|
- !ruby/object:Gem::Version
|
82
82
|
version: '0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: rspec-its
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
83
97
|
- !ruby/object:Gem::Dependency
|
84
98
|
name: factory_bot
|
85
99
|
requirement: !ruby/object:Gem::Requirement
|
@@ -107,10 +121,17 @@ files:
|
|
107
121
|
- app/assets/config/social_man_manifest.js
|
108
122
|
- app/models/action.rb
|
109
123
|
- config/routes.rb
|
124
|
+
- lib/generators/social_man_generator.rb
|
125
|
+
- lib/generators/templates/README
|
126
|
+
- lib/generators/templates/initializer.rb
|
127
|
+
- lib/generators/templates/migration.rb
|
128
|
+
- lib/generators/templates/model.rb
|
110
129
|
- lib/social_man.rb
|
111
130
|
- lib/social_man/action_model.rb
|
112
131
|
- lib/social_man/action_object.rb
|
113
132
|
- lib/social_man/action_subject.rb
|
133
|
+
- lib/social_man/action_thesaurus.rb
|
134
|
+
- lib/social_man/configure.rb
|
114
135
|
- lib/social_man/engine.rb
|
115
136
|
- lib/social_man/railtie.rb
|
116
137
|
- lib/social_man/version.rb
|