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.
Files changed (60) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.md +148 -0
  4. data/Rakefile +32 -0
  5. data/app/assets/config/soc_med_manifest.js +1 -0
  6. data/app/assets/stylesheets/soc_med/application.css +15 -0
  7. data/app/blueprints/base_blueprint.rb +6 -0
  8. data/app/blueprints/blocks/overview_blueprint.rb +7 -0
  9. data/app/blueprints/follows/overview_blueprint.rb +7 -0
  10. data/app/blueprints/likes/overview_blueprint.rb +7 -0
  11. data/app/blueprints/reports/overview_blueprint.rb +7 -0
  12. data/app/controllers/soc_med/application_controller.rb +24 -0
  13. data/app/controllers/soc_med/blocks_controller.rb +28 -0
  14. data/app/controllers/soc_med/follows_controller.rb +28 -0
  15. data/app/controllers/soc_med/likes_controller.rb +28 -0
  16. data/app/controllers/soc_med/reports_controller.rb +29 -0
  17. data/app/errors/soc_med/base.rb +4 -0
  18. data/app/errors/soc_med/blocks/already_exists_error.rb +7 -0
  19. data/app/errors/soc_med/follows/already_exists_error.rb +7 -0
  20. data/app/errors/soc_med/likes/already_exists_error.rb +7 -0
  21. data/app/helpers/soc_med/application_helper.rb +4 -0
  22. data/app/jobs/soc_med/application_job.rb +4 -0
  23. data/app/mailers/soc_med/application_mailer.rb +6 -0
  24. data/app/models/soc_med/application_record.rb +5 -0
  25. data/app/models/soc_med/block.rb +16 -0
  26. data/app/models/soc_med/concerns/soc_med_helper.rb +17 -0
  27. data/app/models/soc_med/follow.rb +35 -0
  28. data/app/models/soc_med/like.rb +38 -0
  29. data/app/models/soc_med/report.rb +16 -0
  30. data/app/views/layouts/soc_med/application.html.erb +15 -0
  31. data/config/routes.rb +6 -0
  32. data/db/migrate/20200605151411_create_soc_med_likes.rb +12 -0
  33. data/db/migrate/20200605151423_create_soc_med_follows.rb +12 -0
  34. data/db/migrate/20200605151437_create_soc_med_blocks.rb +12 -0
  35. data/db/migrate/20200605151450_create_soc_med_reports.rb +12 -0
  36. data/lib/soc_med.rb +21 -0
  37. data/lib/soc_med/concerns/blockable.rb +34 -0
  38. data/lib/soc_med/concerns/followable.rb +34 -0
  39. data/lib/soc_med/concerns/likeable.rb +34 -0
  40. data/lib/soc_med/concerns/reportable.rb +33 -0
  41. data/lib/soc_med/engine.rb +5 -0
  42. data/lib/soc_med/services/base_service.rb +37 -0
  43. data/lib/soc_med/services/blocks/block_base.rb +46 -0
  44. data/lib/soc_med/services/blocks/create.rb +27 -0
  45. data/lib/soc_med/services/blocks/destroy.rb +27 -0
  46. data/lib/soc_med/services/failure.rb +16 -0
  47. data/lib/soc_med/services/follows/create.rb +27 -0
  48. data/lib/soc_med/services/follows/destroy.rb +27 -0
  49. data/lib/soc_med/services/follows/follow_base.rb +46 -0
  50. data/lib/soc_med/services/likes/create.rb +25 -0
  51. data/lib/soc_med/services/likes/destroy.rb +26 -0
  52. data/lib/soc_med/services/likes/like_base.rb +46 -0
  53. data/lib/soc_med/services/no_trigger.rb +10 -0
  54. data/lib/soc_med/services/reports/base_report.rb +46 -0
  55. data/lib/soc_med/services/reports/create.rb +27 -0
  56. data/lib/soc_med/services/reports/destroy.rb +27 -0
  57. data/lib/soc_med/services/success.rb +16 -0
  58. data/lib/soc_med/version.rb +3 -0
  59. data/lib/tasks/soc_med_tasks.rake +4 -0
  60. metadata +180 -0
@@ -0,0 +1,4 @@
1
+ module SocMed
2
+ module ApplicationHelper
3
+ end
4
+ end
@@ -0,0 +1,4 @@
1
+ module SocMed
2
+ class ApplicationJob < ActiveJob::Base
3
+ end
4
+ end
@@ -0,0 +1,6 @@
1
+ module SocMed
2
+ class ApplicationMailer < ActionMailer::Base
3
+ default from: 'from@example.com'
4
+ layout 'mailer'
5
+ end
6
+ end
@@ -0,0 +1,5 @@
1
+ module SocMed
2
+ class ApplicationRecord < ActiveRecord::Base
3
+ self.abstract_class = true
4
+ end
5
+ end
@@ -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
@@ -0,0 +1,15 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>Soc med</title>
5
+ <%= csrf_meta_tags %>
6
+ <%= csp_meta_tag %>
7
+
8
+ <%= stylesheet_link_tag "soc_med/application", media: "all" %>
9
+ </head>
10
+ <body>
11
+
12
+ <%= yield %>
13
+
14
+ </body>
15
+ </html>
@@ -0,0 +1,6 @@
1
+ SocMed::Engine.routes.draw do
2
+ resource :likes, only: %i[create destroy]
3
+ resources :follows, only: %i[create destroy]
4
+ resources :blocks, only: %i[create destroy]
5
+ resources :reports, only: %i[create destroy]
6
+ end
@@ -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
@@ -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,5 @@
1
+ module SocMed
2
+ class Engine < ::Rails::Engine
3
+ isolate_namespace SocMed
4
+ end
5
+ 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