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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8faa448ec53af875988e037161d8c353f147fa31e65578b9923f5aec922d634a
4
- data.tar.gz: 647a1f4dbcc311c1261c60db46f8d6698fa0bceeb8e35462d80c6d7ad9234652
3
+ metadata.gz: bc565ae17296e2e1570eea93006c687b9eb98a46ecfb7cfa34c590de703e09f8
4
+ data.tar.gz: f20b035053e73233c20e151bb9a1f84f44e377eccace08d66cbe662f28acb70c
5
5
  SHA512:
6
- metadata.gz: c8d7159def702ebd429b93a417c943a1fe2c5116d90679a3bc22593ab08ddead64a7b581a5cee214d105e8110c23520b785425d808e0de7b05733949f7ab7233
7
- data.tar.gz: f983ac83dcaebdeaacbb79fbc45bceb69795d2b75693ac2d9cf64622392ef4313c766d2a238d18ecfb11bbaf26ab565f0da53899a86217d996097fe4198644a1
6
+ metadata.gz: 99dc914979f634d4cb22edec6fb2fbfe13ad3b87d8d032c62c0f5d60528753dbcdf6e7ec5050bccb95bdec3962252ad4a83ef138dfcf053795f7f2a6bbe4e7b1
7
+ data.tar.gz: 3db8524fd964a11eb06b60688ef7426dee3973bedcc56fddb8a2b3dbeb6a036c129a1020312d3453e8c026be8df6defc4989cf240341ff89f1bad8c7fb1ebf36
data/app/models/action.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
- # Auto generate with social-man gem.
2
+
3
3
  class Action < ActiveRecord::Base
4
4
  include SocialMan::ActionModel
5
5
  end
@@ -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,4 @@
1
+ SocialMan.configure do |config|
2
+ # Config actions to be used as social actions
3
+ # config.actions = [:like, :star, :follow]
4
+ end
@@ -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
@@ -0,0 +1,3 @@
1
+ class Action < ApplicationRecord
2
+ include SocialMan::ActionModel
3
+ 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 :subject, polymorphic: true
8
- belongs_to :object, polymorphic: true
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 be_taken_action_by(subject)
19
- Action.create subject: subject, object: self
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?(subject)
23
- Action.exists? subject: subject, object: self
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(object)
22
- Action.create subject: self, object: object
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?(object)
26
- Action.exists? subject: self, object: object
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
@@ -1,3 +1,3 @@
1
1
  module SocialMan
2
- VERSION = '0.1.0'
2
+ VERSION = '0.2.0'
3
3
  end
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.1.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-09 00:00:00.000000000 Z
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.2.1
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.2.1
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