soc_med 0.1.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.
- checksums.yaml +7 -0
- data/MIT-LICENSE +20 -0
- data/README.md +148 -0
- data/Rakefile +32 -0
- data/app/assets/config/soc_med_manifest.js +1 -0
- data/app/assets/stylesheets/soc_med/application.css +15 -0
- data/app/blueprints/base_blueprint.rb +6 -0
- data/app/blueprints/blocks/overview_blueprint.rb +7 -0
- data/app/blueprints/follows/overview_blueprint.rb +7 -0
- data/app/blueprints/likes/overview_blueprint.rb +7 -0
- data/app/blueprints/reports/overview_blueprint.rb +7 -0
- data/app/controllers/soc_med/application_controller.rb +24 -0
- data/app/controllers/soc_med/blocks_controller.rb +28 -0
- data/app/controllers/soc_med/follows_controller.rb +28 -0
- data/app/controllers/soc_med/likes_controller.rb +28 -0
- data/app/controllers/soc_med/reports_controller.rb +29 -0
- data/app/errors/soc_med/base.rb +4 -0
- data/app/errors/soc_med/blocks/already_exists_error.rb +7 -0
- data/app/errors/soc_med/follows/already_exists_error.rb +7 -0
- data/app/errors/soc_med/likes/already_exists_error.rb +7 -0
- data/app/helpers/soc_med/application_helper.rb +4 -0
- data/app/jobs/soc_med/application_job.rb +4 -0
- data/app/mailers/soc_med/application_mailer.rb +6 -0
- data/app/models/soc_med/application_record.rb +5 -0
- data/app/models/soc_med/block.rb +16 -0
- data/app/models/soc_med/concerns/soc_med_helper.rb +17 -0
- data/app/models/soc_med/follow.rb +35 -0
- data/app/models/soc_med/like.rb +38 -0
- data/app/models/soc_med/report.rb +16 -0
- data/app/views/layouts/soc_med/application.html.erb +15 -0
- data/config/routes.rb +6 -0
- data/db/migrate/20200605151411_create_soc_med_likes.rb +12 -0
- data/db/migrate/20200605151423_create_soc_med_follows.rb +12 -0
- data/db/migrate/20200605151437_create_soc_med_blocks.rb +12 -0
- data/db/migrate/20200605151450_create_soc_med_reports.rb +12 -0
- data/lib/soc_med.rb +21 -0
- data/lib/soc_med/concerns/blockable.rb +34 -0
- data/lib/soc_med/concerns/followable.rb +34 -0
- data/lib/soc_med/concerns/likeable.rb +34 -0
- data/lib/soc_med/concerns/reportable.rb +33 -0
- data/lib/soc_med/engine.rb +5 -0
- data/lib/soc_med/services/base_service.rb +37 -0
- data/lib/soc_med/services/blocks/block_base.rb +46 -0
- data/lib/soc_med/services/blocks/create.rb +27 -0
- data/lib/soc_med/services/blocks/destroy.rb +27 -0
- data/lib/soc_med/services/failure.rb +16 -0
- data/lib/soc_med/services/follows/create.rb +27 -0
- data/lib/soc_med/services/follows/destroy.rb +27 -0
- data/lib/soc_med/services/follows/follow_base.rb +46 -0
- data/lib/soc_med/services/likes/create.rb +25 -0
- data/lib/soc_med/services/likes/destroy.rb +26 -0
- data/lib/soc_med/services/likes/like_base.rb +46 -0
- data/lib/soc_med/services/no_trigger.rb +10 -0
- data/lib/soc_med/services/reports/base_report.rb +46 -0
- data/lib/soc_med/services/reports/create.rb +27 -0
- data/lib/soc_med/services/reports/destroy.rb +27 -0
- data/lib/soc_med/services/success.rb +16 -0
- data/lib/soc_med/version.rb +3 -0
- data/lib/tasks/soc_med_tasks.rake +4 -0
- metadata +180 -0
@@ -0,0 +1,16 @@
|
|
1
|
+
module SocMed
|
2
|
+
class Block < ApplicationRecord
|
3
|
+
belongs_to :target, polymorphic: true
|
4
|
+
belongs_to :owner, polymorphic: true
|
5
|
+
|
6
|
+
before_validation :raise_already_liked_error_if_required, on: :create
|
7
|
+
|
8
|
+
validates :target_id, uniqueness: {scope: %i[target_type owner_id owner_type], message: "has already been blocked."}
|
9
|
+
|
10
|
+
private
|
11
|
+
|
12
|
+
def raise_already_followd_error_if_required
|
13
|
+
raise SocMed::Follows::AlreadyExistsError.new("#{owner_type} has already blocked that #{target_type}") if owner.blockable_objects.exists?(target: target)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module SocMed
|
2
|
+
module Concerns
|
3
|
+
module SocMedHelper
|
4
|
+
|
5
|
+
def raise_not_implemented_error
|
6
|
+
raise NotImplementedError unless target.respond_to?("number_of_#{self.class.to_s.underscore.split('/')[-1].pluralize}")
|
7
|
+
end
|
8
|
+
|
9
|
+
def update_count(attribute, operator)
|
10
|
+
count = target.send(attribute).send(operator, 1)
|
11
|
+
|
12
|
+
target.update("#{attribute}" => count)
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module SocMed
|
2
|
+
class Follow < ApplicationRecord
|
3
|
+
include SocMed::SocMedHelper
|
4
|
+
|
5
|
+
belongs_to :target, polymorphic: true
|
6
|
+
belongs_to :owner, polymorphic: true
|
7
|
+
|
8
|
+
|
9
|
+
before_validation :raise_already_liked_error_if_required, on: :create
|
10
|
+
before_validation :raise_not_implemented_error, on: :create
|
11
|
+
before_commit :increment_number_of_follows, on: :create
|
12
|
+
before_destroy :decrement_number_of_follows
|
13
|
+
|
14
|
+
validates :target_id, uniqueness: {scope: %i[target_type owner_id owner_type], message: "has already been followed."}
|
15
|
+
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
def increment_number_of_follows
|
20
|
+
raise_not_implemented_error
|
21
|
+
|
22
|
+
update_count(:number_of_follows, :+)
|
23
|
+
end
|
24
|
+
|
25
|
+
def decrement_number_of_follows
|
26
|
+
raise_not_implemented_error
|
27
|
+
|
28
|
+
update_count(:number_of_follows, :-)
|
29
|
+
end
|
30
|
+
|
31
|
+
def raise_already_followd_error_if_required
|
32
|
+
raise SocMed::Follows::AlreadyExistsError.new("#{owner_type} has already followed that #{target_type}") if owner.followable_objects.exists?(target: target)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require_relative './concerns/soc_med_helper'
|
2
|
+
|
3
|
+
module SocMed
|
4
|
+
class Like < ::ApplicationRecord
|
5
|
+
include Concerns::SocMedHelper
|
6
|
+
|
7
|
+
belongs_to :target, polymorphic: true
|
8
|
+
belongs_to :owner, polymorphic: true
|
9
|
+
|
10
|
+
before_validation :raise_already_liked_error_if_required, on: :create
|
11
|
+
before_validation :raise_not_implemented_error, on: :create
|
12
|
+
before_commit :increment_number_of_likes, on: :create
|
13
|
+
before_destroy :decrement_number_of_likes
|
14
|
+
|
15
|
+
validates :target_id, uniqueness: {scope: %i[target_type owner_id owner_type], message: "has already been liked."}
|
16
|
+
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def increment_number_of_likes
|
21
|
+
raise_not_implemented_error
|
22
|
+
|
23
|
+
update_count(:number_of_likes, :+)
|
24
|
+
end
|
25
|
+
|
26
|
+
def decrement_number_of_likes
|
27
|
+
raise_not_implemented_error
|
28
|
+
|
29
|
+
update_count(:number_of_likes, :-)
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
def raise_already_liked_error_if_required
|
35
|
+
raise SocMed::Likes::AlreadyExistsError.new("#{owner_type} has already liked that #{target_type}") if owner.likeable_objects.exists?(target: target)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module SocMed
|
2
|
+
class Report < ApplicationRecord
|
3
|
+
belongs_to :target, polymorphic: true
|
4
|
+
belongs_to :owner, polymorphic: true
|
5
|
+
|
6
|
+
before_validation :raise_already_liked_error_if_required, on: :create
|
7
|
+
|
8
|
+
validates :target_id, uniqueness: {scope: %i[target_type owner_id owner_type], message: "has already been reported."}
|
9
|
+
|
10
|
+
private
|
11
|
+
|
12
|
+
def raise_already_followd_error_if_required
|
13
|
+
raise SocMed::Reports::AlreadyExistsError.new("#{owner_type} has already reported that #{target_type}") if owner.reportable_objects.exists?(target: target)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
data/config/routes.rb
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
class CreateSocMedLikes < ActiveRecord::Migration[6.0]
|
2
|
+
def change
|
3
|
+
create_table :soc_med_likes do |t|
|
4
|
+
t.references :target, null: false, polymorphic: true
|
5
|
+
t.references :owner, null: false, polymorphic: true
|
6
|
+
|
7
|
+
t.timestamps
|
8
|
+
end
|
9
|
+
|
10
|
+
add_index :soc_med_likes, %i[target_id target_type owner_id owner_type], unique: true, name: :idx_soc_med_likes_on_target_and_owner
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
class CreateSocMedFollows < ActiveRecord::Migration[6.0]
|
2
|
+
def change
|
3
|
+
create_table :soc_med_follows do |t|
|
4
|
+
t.references :target, null: false, polymorphic: true
|
5
|
+
t.references :owner, null: false, polymorphic: true
|
6
|
+
|
7
|
+
t.timestamps
|
8
|
+
end
|
9
|
+
|
10
|
+
add_index :soc_med_follows, %i[target_id target_type owner_id owner_type], unique: true, name: :idx_soc_med_follows_on_target_and_owner
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
class CreateSocMedBlocks < ActiveRecord::Migration[6.0]
|
2
|
+
def change
|
3
|
+
create_table :soc_med_blocks do |t|
|
4
|
+
t.references :target, null: false, polymorphic: true
|
5
|
+
t.references :owner, null: false, polymorphic: true
|
6
|
+
|
7
|
+
t.timestamps
|
8
|
+
end
|
9
|
+
|
10
|
+
add_index :soc_med_blocks, %i[target_id target_type owner_id owner_type], unique: true, name: :idx_soc_med_blocks_on_target_and_owner
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
class CreateSocMedReports < ActiveRecord::Migration[6.0]
|
2
|
+
def change
|
3
|
+
create_table :soc_med_reports do |t|
|
4
|
+
t.references :target, null: false, polymorphic: true
|
5
|
+
t.references :owner, null: false, polymorphic: true
|
6
|
+
|
7
|
+
t.timestamps
|
8
|
+
end
|
9
|
+
|
10
|
+
add_index :soc_med_reports, %i[target_id target_type owner_id owner_type], unique: true, name: :idx_soc_med_reports_on_target_and_owner
|
11
|
+
end
|
12
|
+
end
|
data/lib/soc_med.rb
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
require "soc_med/engine"
|
2
|
+
require 'soc_med/concerns/likeable'
|
3
|
+
require 'soc_med/concerns/followable'
|
4
|
+
require 'soc_med/concerns/blockable'
|
5
|
+
require 'soc_med/concerns/reportable'
|
6
|
+
require 'soc_med/services/likes/create'
|
7
|
+
require 'soc_med/services/likes/destroy'
|
8
|
+
require 'soc_med/services/follows/create'
|
9
|
+
require 'soc_med/services/follows/destroy'
|
10
|
+
require 'soc_med/services/reports/create'
|
11
|
+
require 'soc_med/services/reports/destroy'
|
12
|
+
require 'soc_med/services/blocks/create'
|
13
|
+
require 'soc_med/services/blocks/destroy'
|
14
|
+
|
15
|
+
module SocMed
|
16
|
+
mattr_accessor :owner_class
|
17
|
+
|
18
|
+
def self.owner_class
|
19
|
+
@@owner_class.to_s.classify.constantize
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module SocMed
|
2
|
+
module Concerns
|
3
|
+
module Blockable
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
|
6
|
+
included do
|
7
|
+
has_many :blocks, class_name: 'SocMed::Block', as: :target, dependent: :destroy
|
8
|
+
has_many :blockable_objects, class_name: 'SocMed::Block', as: :owner, dependent: :destroy
|
9
|
+
end
|
10
|
+
|
11
|
+
class_methods do
|
12
|
+
def blockable(*attributes)
|
13
|
+
attributes = [attributes] unless attributes.is_a?(Array)
|
14
|
+
|
15
|
+
attributes.each do |attribute|
|
16
|
+
class_eval "has_many :by_blocking_#{attribute}, -> { order(created_at: :desc) }, class_name: 'SocMed::Block', source: :owner, source_type: '#{attribute.to_s.classify}', foreign_key: :owner_id, dependent: :destroy"
|
17
|
+
class_eval "has_many :blocked_#{attribute}, through: :by_blocking_#{attribute}, source: :target, source_type: '#{attribute.to_s.classify}'"
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def blocker(*attributes)
|
22
|
+
attributes = [attributes] unless attributes.is_a?(Array)
|
23
|
+
|
24
|
+
attributes.each do |attribute|
|
25
|
+
class_eval "has_many :by_blocked_#{attribute}, -> { order(created_at: :desc) }, class_name: 'SocMed::Block', source: :target, source_type: '#{attribute.to_s.classify}', foreign_key: :target_id, dependent: :destroy"
|
26
|
+
class_eval "has_many :blocked_by_#{attribute}, through: :by_blocked_#{attribute}, source: :owner, source_type: '#{attribute.to_s.classify}'"
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module SocMed
|
2
|
+
module Concerns
|
3
|
+
module Followable
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
|
6
|
+
included do
|
7
|
+
has_many :follows, class_name: 'SocMed::Follow', as: :target, dependent: :destroy
|
8
|
+
has_many :followable_objects, class_name: 'SocMed::Follow', as: :owner, dependent: :destroy
|
9
|
+
end
|
10
|
+
|
11
|
+
class_methods do
|
12
|
+
def followable(*attributes)
|
13
|
+
attributes = [attributes] unless attributes.is_a?(Array)
|
14
|
+
|
15
|
+
attributes.each do |attribute|
|
16
|
+
class_eval "has_many :by_following_#{attribute}, -> { order(created_at: :desc) }, class_name: 'SocMed::Follow', source: :owner, source_type: '#{attribute.to_s.classify}', foreign_key: :owner_id, dependent: :destroy"
|
17
|
+
class_eval "has_many :followed_#{attribute}, through: :by_following_#{attribute}, source: :target, source_type: '#{attribute.to_s.classify}'"
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def follower(*attributes)
|
22
|
+
attributes = [attributes] unless attributes.is_a?(Array)
|
23
|
+
|
24
|
+
attributes.each do |attribute|
|
25
|
+
class_eval "has_many :by_followed_#{attribute}, -> { order(created_at: :desc) }, class_name: 'SocMed::Follow', source: :target, source_type: '#{attribute.to_s.classify}', foreign_key: :target_id, dependent: :destroy"
|
26
|
+
class_eval "has_many :followed_by_#{attribute}, through: :by_followed_#{attribute}, source: :owner, source_type: '#{attribute.to_s.classify}'"
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module SocMed
|
2
|
+
module Concerns
|
3
|
+
module Likeable
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
|
6
|
+
included do
|
7
|
+
has_many :likes, class_name: 'SocMed::Like', as: :target, dependent: :destroy
|
8
|
+
has_many :likeable_objects, class_name: 'SocMed::Like', as: :owner, dependent: :destroy
|
9
|
+
end
|
10
|
+
|
11
|
+
class_methods do
|
12
|
+
def likeable(*attributes)
|
13
|
+
attributes = [attributes] unless attributes.is_a?(Array)
|
14
|
+
|
15
|
+
attributes.each do |attribute|
|
16
|
+
class_eval "has_many :by_liking_#{attribute}, -> { order(created_at: :desc) }, class_name: 'SocMed::Like', source: :owner, source_type: '#{attribute.to_s.classify}', foreign_key: :owner_id, dependent: :destroy"
|
17
|
+
class_eval "has_many :liked_#{attribute}, through: :by_liking_#{attribute}, source: :target, source_type: '#{attribute.to_s.classify}'"
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def liker(*attributes)
|
22
|
+
attributes = [attributes] unless attributes.is_a?(Array)
|
23
|
+
|
24
|
+
attributes.each do |attribute|
|
25
|
+
class_eval "has_many :by_liked_#{attribute}, -> { order(created_at: :desc) }, class_name: 'SocMed::Like', source: :target, source_type: '#{attribute.to_s.classify}', foreign_key: :target_id, dependent: :destroy"
|
26
|
+
class_eval "has_many :liked_by_#{attribute}, through: :by_liked_#{attribute}, source: :owner, source_type: '#{attribute.to_s.classify}'"
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module SocMed
|
2
|
+
module Concerns
|
3
|
+
module Reportable
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
|
6
|
+
included do
|
7
|
+
has_many :reports, class_name: 'SocMed::Report', as: :target, dependent: :destroy
|
8
|
+
has_many :reportable_objects, class_name: 'SocMed::Report', as: :owner, dependent: :destroy
|
9
|
+
end
|
10
|
+
|
11
|
+
class_methods do
|
12
|
+
def reportable(*attributes)
|
13
|
+
attributes = [attributes] unless attributes.is_a?(Array)
|
14
|
+
|
15
|
+
attributes.each do |attribute|
|
16
|
+
class_eval "has_many :by_reporting_#{attribute}, -> { order(created_at: :desc) }, class_name: 'SocMed::Report', source: :owner, source_type: '#{attribute.to_s.classify}', foreign_key: :owner_id, dependent: :destroy"
|
17
|
+
class_eval "has_many :reported_#{attribute}, through: :by_reporting_#{attribute}, source: :target, source_type: '#{attribute.to_s.classify}'"
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def reporter(*attributes)
|
22
|
+
attributes = [attributes] unless attributes.is_a?(Array)
|
23
|
+
|
24
|
+
attributes.each do |attribute|
|
25
|
+
class_eval "has_many :by_reported_#{attribute}, -> { order(created_at: :desc) }, class_name: 'SocMed::Report', source: :target, source_type: '#{attribute.to_s.classify}', foreign_key: :target_id, dependent: :destroy"
|
26
|
+
class_eval "has_many :reported_by_#{attribute}, through: :by_reported_#{attribute}, source: :owner, source_type: '#{attribute.to_s.classify}'"
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require 'active_record'
|
2
|
+
require 'soc_med/services/no_trigger'
|
3
|
+
require 'soc_med/services/success'
|
4
|
+
require 'soc_med/services/failure'
|
5
|
+
|
6
|
+
module SocMed
|
7
|
+
module Services
|
8
|
+
class BaseService
|
9
|
+
attr_reader :params
|
10
|
+
|
11
|
+
def self.call(params, &block)
|
12
|
+
new( params).call(&block)
|
13
|
+
end
|
14
|
+
|
15
|
+
def initialize(params)
|
16
|
+
@params = params
|
17
|
+
end
|
18
|
+
|
19
|
+
private_class_method :new
|
20
|
+
|
21
|
+
def call(&block)
|
22
|
+
raise NotImplementedError
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
def target
|
28
|
+
raise NotImplementedError
|
29
|
+
end
|
30
|
+
|
31
|
+
def owner
|
32
|
+
raise NotImplementedError
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
require_relative '../base_service'
|
2
|
+
|
3
|
+
module SocMed
|
4
|
+
module Services
|
5
|
+
module Blocks
|
6
|
+
class BlockBase < BaseService
|
7
|
+
|
8
|
+
private
|
9
|
+
|
10
|
+
def block
|
11
|
+
block = owner.blockable_objects.find_by(target: target)
|
12
|
+
raise ActiveRecord::RecordNotFound unless block
|
13
|
+
|
14
|
+
block
|
15
|
+
end
|
16
|
+
|
17
|
+
def target
|
18
|
+
target_type, target_id = target_info
|
19
|
+
target = target_type.classify.constantize.find_by(id: target_id)
|
20
|
+
raise ActiveRecord::RecordNotFound unless target
|
21
|
+
|
22
|
+
target
|
23
|
+
end
|
24
|
+
|
25
|
+
def target_info
|
26
|
+
return params[:block][:target_type], params[:block][:target_id] unless params[:block].nil?
|
27
|
+
return params[:target_type], params[:target_id]
|
28
|
+
end
|
29
|
+
|
30
|
+
def owner
|
31
|
+
owner_type, owner_id = owner_info
|
32
|
+
owner = SocMed.owner_class.find_by(id: owner_id)
|
33
|
+
raise ActiveRecord::RecordNotFound unless owner
|
34
|
+
|
35
|
+
owner
|
36
|
+
end
|
37
|
+
|
38
|
+
def owner_info
|
39
|
+
return params[:block][:owner_type], params[:block][:owner_id] unless params[:block].nil?
|
40
|
+
return params[:owner_type], params[:owner_id]
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|