soc_med 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
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,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: b9e72d4977e041a7094a05d9159bdc904a2d962f69cbf4488c8e1deb3affca9a
4
+ data.tar.gz: 69fa2e2a15ccab49f551997505d5613d971227bea7fe78d9f025d86e9d9b2902
5
+ SHA512:
6
+ metadata.gz: 46b00d2074041e967eedb6cd6fdf21ffe1c98bac9f7bcf2a95c53aa623445daf32bfcf2000a8b678969e07fbaf4ef1acde5f36273e82ab675b4ae1d72a0225c9
7
+ data.tar.gz: eab8bf92c6315a2e6a73c75e98482158f8b4b18be80c4387ab5678f885f39b6f8fb777af8cf0bb070743caa476c6fa2c1ce143ab83b0ef6d4313a05e5b6d511b
@@ -0,0 +1,20 @@
1
+ Copyright 2020 Mike Heft
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,148 @@
1
+ # SocMed
2
+ ![Gem](https://img.shields.io/gem/dt/soc_med?style=plastic)
3
+ ![Gem](https://img.shields.io/gem/v/soc_med?style=plastic)
4
+
5
+ SocMed adds SOCial MEDia functionality such as liking, following, reporting, and blocking to your Rails application.
6
+
7
+ ## Installation
8
+ Add this line to your application's Gemfile:
9
+
10
+ ```ruby
11
+ gem 'soc_med'
12
+ ```
13
+
14
+ And then execute:
15
+ ```bash
16
+ $ bundle
17
+ ```
18
+
19
+ Or install it yourself as:
20
+ ```bash
21
+ $ gem install soc_med
22
+ ```
23
+
24
+ After installing the gem in your application, you need to copy the migrations from the gem to your application:
25
+ ```bash
26
+ $ rails soc_med:install:migrations
27
+ ```
28
+
29
+ Once the migrations are copied, you can delete any that you do not currently need in your application. If you later decide
30
+ that you want those models/functionality, you can simply rerun the above command to recopy the missing migrations.
31
+
32
+
33
+ ## Usage
34
+
35
+ #### Mount the gem
36
+ ```ruby
37
+ # config/routes.rb
38
+
39
+ Rails.application.routes.draw do
40
+ mount SocMed::Engine => '/soc_med'
41
+ end
42
+ ```
43
+
44
+ - The Services used to create the social media objects, are available if you do not wish to use the engine's controllers through the `mount` method.
45
+
46
+ #### Include the relevant modules
47
+
48
+ To use the relationships in your models, you must include the modules in the `owner` and `target` classes.
49
+ For example, a User is able to 'follow' other users and 'like' an Item.
50
+
51
+ ```ruby
52
+ class User < ApplicationRecord
53
+ include SocMed::Concerns::Likeable
54
+ include SocMed::Concerns::Follwable
55
+ include SocMed::Concerns::Blockable
56
+ include SocMed::Concerns::Reportable
57
+
58
+ likeable :items
59
+ followable :users
60
+ follower :users
61
+ reportable :users, :items
62
+ ...
63
+ end
64
+
65
+ class Item < ApplicationRecord
66
+ include SocMed::Concerns::Likeable
67
+ include SocMed::Concerns::Follwable
68
+ include SocMed::Concerns::Blockable
69
+ include SocMed::Concerns::Reportable
70
+
71
+ liker :users
72
+ reporter :users
73
+ ...
74
+ end
75
+ ```
76
+
77
+ You can omit any module that you do not want in the respective model.
78
+ The class methods called in the models provide the required relationships, ie:
79
+
80
+ - A User is able to 'like' an Item and Post
81
+ - `likeable :items, :posts`
82
+ - This provides the following relationships to differentiate the liked models if required. Otherwise, you may just use the `likeable_objects` relationship.
83
+ - `has_many :liked_items`
84
+ - `has_many :liked_posts`
85
+ - An Item is able to be 'liked' by a user
86
+ - `liker :users, :admins`
87
+ - This provides the following relationships like above to separate the collection types or you may use the `likes` relationship
88
+ - `has_many :liked_by_users`
89
+ - `has_many :liked_by_admins`
90
+ - The `liked_` and `liked_by_` relationships are an example. With the other available modules, the respective names will be interpolated if and when you provide the symbols as arguments to the class methods.
91
+
92
+ #### Creating SocMed Objects
93
+
94
+ Simply send `POST` or `DELETE` requests with the the relevant top level key, ie:
95
+
96
+ ```json
97
+ {
98
+ "like": {
99
+ "owner_id": 1,
100
+ "owner_type": "user",
101
+ "target_id": 1,
102
+ "target_type": "item"
103
+ }
104
+ }
105
+ ```
106
+ With `"like"` being substituted for the relevant `SocMed` module: `like, follow, block, report`
107
+
108
+ - Routes for each are:
109
+ - Like
110
+ - `/likes`
111
+ - Follow
112
+ - `follows`
113
+ - Block
114
+ - `/blocks`
115
+ - Report
116
+ - `/reports`
117
+ - The return for each is serialized json, with the top level kep changing depending on the object you're creating
118
+
119
+ ```json
120
+ {
121
+ "message": null,
122
+ "like": {
123
+ "owner_id": 1,
124
+ "owner_type": "user",
125
+ "target_type": "item",
126
+ "target_id": 1
127
+ }
128
+ }
129
+ ```
130
+
131
+ For errors, the return will be formatted as:
132
+ ```json
133
+ {
134
+ "message": "Error message/object"
135
+ }
136
+ ```
137
+
138
+
139
+
140
+
141
+
142
+ ## Contributing
143
+ Coming Soon
144
+
145
+ ## License
146
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
147
+
148
+ [![paypal](https://www.paypalobjects.com/en_US/i/btn/btn_donateCC_LG.gif)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=4MFMTB9YYQFR8)
@@ -0,0 +1,32 @@
1
+ begin
2
+ require 'bundler/setup'
3
+ rescue LoadError
4
+ puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
5
+ end
6
+
7
+ require 'rdoc/task'
8
+
9
+ RDoc::Task.new(:rdoc) do |rdoc|
10
+ rdoc.rdoc_dir = 'rdoc'
11
+ rdoc.title = 'SocMed'
12
+ rdoc.options << '--line-numbers'
13
+ rdoc.rdoc_files.include('README.md')
14
+ rdoc.rdoc_files.include('lib/**/*.rb')
15
+ end
16
+
17
+ APP_RAKEFILE = File.expand_path("test/dummy/Rakefile", __dir__)
18
+ load 'rails/tasks/engine.rake'
19
+
20
+ load 'rails/tasks/statistics.rake'
21
+
22
+ require 'bundler/gem_tasks'
23
+
24
+ require 'rake/testtask'
25
+
26
+ Rake::TestTask.new(:test) do |t|
27
+ t.libs << 'test'
28
+ t.pattern = 'test/**/*_test.rb'
29
+ t.verbose = false
30
+ end
31
+
32
+ task default: :test
@@ -0,0 +1 @@
1
+ //= link_directory ../stylesheets/soc_med .css
@@ -0,0 +1,15 @@
1
+ /*
2
+ * This is a manifest file that'll be compiled into application.css, which will include all the files
3
+ * listed below.
4
+ *
5
+ * Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
6
+ * or any plugin's vendor/assets/stylesheets directory can be referenced here using a relative path.
7
+ *
8
+ * You're free to add application-wide styles to this file and they'll appear at the bottom of the
9
+ * compiled file so the styles you add here take precedence over styles defined in any other CSS/SCSS
10
+ * files in this directory. Styles in this file should be added after the last require_* statement.
11
+ * It is generally better to create a new file per style scope.
12
+ *
13
+ *= require_tree .
14
+ *= require_self
15
+ */
@@ -0,0 +1,6 @@
1
+ require 'blueprinter'
2
+
3
+ class BaseBlueprint < Blueprinter::Base
4
+ identifier :id
5
+ fields :owner_id, :owner_type, :target_id, :target_type
6
+ end
@@ -0,0 +1,7 @@
1
+ require_relative '../base_blueprint'
2
+
3
+ module Blocks
4
+ class OverviewBlueprint < BaseBlueprint
5
+
6
+ end
7
+ end
@@ -0,0 +1,7 @@
1
+ require_relative '../base_blueprint'
2
+
3
+ module Follows
4
+ class OverviewBlueprint < BaseBlueprint
5
+
6
+ end
7
+ end
@@ -0,0 +1,7 @@
1
+ require_relative '../base_blueprint'
2
+
3
+ module Likes
4
+ class OverviewBlueprint < BaseBlueprint
5
+
6
+ end
7
+ end
@@ -0,0 +1,7 @@
1
+ require_relative '../base_blueprint'
2
+
3
+ module Reports
4
+ class OverviewBlueprint < BaseBlueprint
5
+
6
+ end
7
+ end
@@ -0,0 +1,24 @@
1
+ require 'dry_serialization/blueprinter'
2
+
3
+ module SocMed
4
+ class ApplicationController < ActionController::Base
5
+ include DrySerialization::Blueprinter
6
+ protect_from_forgery unless: -> { request.format.json? }
7
+
8
+ def error_response(error)
9
+ default_response = default_response(error)
10
+ render json: default_response
11
+ end
12
+
13
+ def success_response(data, message = nil)
14
+ default_response = default_response(message, data)
15
+ render json: default_response
16
+ end
17
+
18
+ private
19
+
20
+ def default_response(message, data = {})
21
+ { message: message }.merge(data)
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,28 @@
1
+ require 'soc_med/services/blocks/create'
2
+ require 'soc_med/services/blocks/destroy'
3
+ require_relative '../../blueprints/blocks/overview_blueprint'
4
+
5
+ module SocMed
6
+ class BlocksController < ApplicationController
7
+ def create
8
+ block_service::Create.call(params) do |success, failure|
9
+ success.call { |object| success_response(block: serialized_resource(object, ::Blocks::OverviewBlueprint)) }
10
+ failure.call(&method(:error_response))
11
+ end
12
+ end
13
+
14
+ def destroy
15
+ block_service::Destroy.call(params) do |success, failure|
16
+ success.call { success_response(block: { destroyed: true }) }
17
+ failure.call(&method(:error_response))
18
+ end
19
+ end
20
+
21
+ private
22
+
23
+ def block_service
24
+ SocMed::Services::Blocks
25
+ end
26
+
27
+ end
28
+ end
@@ -0,0 +1,28 @@
1
+ require 'soc_med/services/follows/create'
2
+ require 'soc_med/services/follows/destroy'
3
+ require_relative '../../blueprints/follows/overview_blueprint'
4
+
5
+ module SocMed
6
+ class FollowsController < ApplicationController
7
+ def create
8
+ follow_service::Create.call(params) do |success, failure|
9
+ success.call { |object| success_response(follow: serialized_resource(object, ::Follows::OverviewBlueprint)) }
10
+ failure.call(&method(:error_response))
11
+ end
12
+ end
13
+
14
+ def destroy
15
+ follow_service::Destroy.call(params) do |success, failure|
16
+ success.call { success_response(follow: { destroyed: true }) }
17
+ failure.call(&method(:error_response))
18
+ end
19
+ end
20
+
21
+ private
22
+
23
+ def follow_service
24
+ SocMed::Services::Follows
25
+ end
26
+
27
+ end
28
+ end
@@ -0,0 +1,28 @@
1
+ require 'soc_med/services/likes/create'
2
+ require 'soc_med/services/likes/destroy'
3
+ require_relative '../../blueprints/likes/overview_blueprint'
4
+
5
+ module SocMed
6
+ class LikesController < ApplicationController
7
+ def create
8
+ like_service::Create.call(params) do |success, failure|
9
+ success.call { |object| success_response(like: serialized_resource(object, ::Likes::OverviewBlueprint)) }
10
+ failure.call(&method(:error_response))
11
+ end
12
+ end
13
+
14
+ def destroy
15
+ like_service::Destroy.call(params) do |success, failure|
16
+ success.call { success_response(like: { destroyed: true }) }
17
+ failure.call(&method(:error_response))
18
+ end
19
+ end
20
+
21
+ private
22
+
23
+ def like_service
24
+ SocMed::Services::Likes
25
+ end
26
+
27
+ end
28
+ end
@@ -0,0 +1,29 @@
1
+ require 'soc_med/services/reports/create'
2
+ require 'soc_med/services/reports/destroy'
3
+ require_relative '../../blueprints/reports/overview_blueprint'
4
+
5
+
6
+ module SocMed
7
+ class ReportsController < ApplicationController
8
+ def create
9
+ report_service::Create.call(params) do |success, failure|
10
+ success.call { |object| success_response(report: serialized_resource(object, ::Reports::OverviewBlueprint)) }
11
+ failure.call(&method(:error_response))
12
+ end
13
+ end
14
+
15
+ def destroy
16
+ report_service::Destroy.call(params) do |success, failure|
17
+ success.call { success_response(report: { destroyed: true }) }
18
+ failure.call(&method(:error_response))
19
+ end
20
+ end
21
+
22
+ private
23
+
24
+ def report_service
25
+ SocMed::Services::Reports
26
+ end
27
+
28
+ end
29
+ end
@@ -0,0 +1,4 @@
1
+ module SocMed
2
+ class Base < StandardError
3
+ end
4
+ end
@@ -0,0 +1,7 @@
1
+ module SocMed
2
+ module Follows
3
+ class AlreadyExistsError < Base
4
+ end
5
+
6
+ end
7
+ end
@@ -0,0 +1,7 @@
1
+ module SocMed
2
+ module Follows
3
+ class AlreadyExistsError < Base
4
+ end
5
+
6
+ end
7
+ end
@@ -0,0 +1,7 @@
1
+ module SocMed
2
+ module Likes
3
+ class AlreadyExistsError < Base
4
+ end
5
+
6
+ end
7
+ end