upframework 0.2.0 → 0.2.6
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +84 -3
- data/app/controllers/upframework/api_extensions.rb +30 -0
- data/app/controllers/upframework/resources_controller.rb +95 -0
- data/app/controllers/upframework/searches_controller.rb +1 -5
- data/app/searches/upframework/base_search.rb +10 -3
- data/app/services/upframework/base_service.rb +1 -1
- data/config/routes.rb +1 -0
- data/lib/upframework.rb +0 -1
- data/lib/upframework/engine.rb +4 -0
- data/lib/upframework/version.rb +1 -1
- metadata +32 -4
- data/app/controllers/upframework/api_controller.rb +0 -33
- data/lib/upframework/searches/routes.rb +0 -14
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 975f100f65cdf98ae206146f86ce3cbfda572225a86038ddd0efa62fa53812a9
|
4
|
+
data.tar.gz: 2d26dfc94585092d1e821c57c232da954d27d1efe5a895c8586570196bea47d5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 84b5bcebf37ae42d2be82bfc0511cbf56b574104d5f1cc89f7a0392262b363b2ae9f56c1cad6aa04ebcd3573b5b98e611bea747be73d145bf6d00b595f693538
|
7
|
+
data.tar.gz: 6f7cdfb6e2b447504d502a53d1e9856eb5f99de196c36a8a585283b010c67103bfad1f26bdce7079a8f15f6177c3a5c5800b7621c10dd4079d798e42340a9c63
|
data/README.md
CHANGED
@@ -1,8 +1,89 @@
|
|
1
1
|
# Upframework
|
2
|
-
|
2
|
+
Add features on top of Rails, Especially for APIs. This was created to make structural code reusable to other projects (not solving the same problem all over again). And to make the main application less bloated and only contain domain specific code as much as possible.
|
3
3
|
|
4
|
-
|
5
|
-
|
4
|
+
#### The following features are available.
|
5
|
+
- Creates (create, read, update, destroy) action methods for resources.
|
6
|
+
- Has render helpers for API or socket responses. ex. Converting models to its designated serializer.
|
7
|
+
- Converts snake case request params (from js standard) to underscore params (ruby standard)
|
8
|
+
- Searches layer under app/searches. Usually used for form searches.
|
9
|
+
- Services layer under app/services. For single responsibility domain-specific logic code.
|
10
|
+
- Exception notifier and API error response handler.
|
11
|
+
|
12
|
+
## Basic Usage
|
13
|
+
#### Controllers
|
14
|
+
```ruby
|
15
|
+
# app/controllers
|
16
|
+
# create,show,update,destroy methods are available by default
|
17
|
+
class ProjectsController < Upframework::ResourcesController
|
18
|
+
# Example of broadcasting with a serialized object using ActionCables.
|
19
|
+
def udate
|
20
|
+
super do
|
21
|
+
channel = @project.user
|
22
|
+
broadcast_serialized(channel, resource: @project, event: "Project Updated")
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
# Example of rendering serialized responsed. This is using fast_jsonapi serializer.
|
27
|
+
def custom_action
|
28
|
+
render_serialized @project
|
29
|
+
end
|
30
|
+
end
|
31
|
+
```
|
32
|
+
|
33
|
+
#### Searches
|
34
|
+
```ruby
|
35
|
+
#app/searches
|
36
|
+
class ProjectSearch < Upframework::BaseSearch
|
37
|
+
def post_initialize
|
38
|
+
@per_page = 10
|
39
|
+
@scope = Project.accessible_by(@current_ability)
|
40
|
+
end
|
41
|
+
|
42
|
+
def execute
|
43
|
+
# query logic here using scope object defined above
|
44
|
+
# by default results are paginated
|
45
|
+
end
|
46
|
+
end
|
47
|
+
```
|
48
|
+
```
|
49
|
+
#search api available in
|
50
|
+
/search?resource=Project&arg1=""&arg2=""
|
51
|
+
```
|
52
|
+
|
53
|
+
#### Services
|
54
|
+
```ruby
|
55
|
+
#app/services
|
56
|
+
class Project::SubmitService < Upframework::BaseService
|
57
|
+
def post_initialize(id:, **attrs)
|
58
|
+
@project = Project.find(id)
|
59
|
+
end
|
60
|
+
|
61
|
+
def execute
|
62
|
+
# put main logic here
|
63
|
+
# ...
|
64
|
+
project.save
|
65
|
+
end
|
66
|
+
|
67
|
+
def result
|
68
|
+
project
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
service = Project::SubmitService.run
|
73
|
+
service.result => <Project: Instance>
|
74
|
+
service.success? => true/false
|
75
|
+
```
|
76
|
+
|
77
|
+
#### Routes
|
78
|
+
```ruby
|
79
|
+
#config/routes
|
80
|
+
mount Upframework::Engine => /path
|
81
|
+
```
|
82
|
+
routes being available
|
83
|
+
```
|
84
|
+
GET /search
|
85
|
+
POST /services/:service_name
|
86
|
+
```
|
6
87
|
|
7
88
|
## Installation
|
8
89
|
Add this line to your application's Gemfile:
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module Upframework
|
2
|
+
module ApiExtensions
|
3
|
+
extend ::ActiveSupport::Concern
|
4
|
+
|
5
|
+
included do
|
6
|
+
include ::DeviseTokenAuth::Concerns::SetUserByToken
|
7
|
+
include ::Upframework::ErrorHandler
|
8
|
+
include ::Upframework::TransformParamKeys
|
9
|
+
include ::Upframework::ServiceEndpoint
|
10
|
+
include ::Upframework::RenderExtensions
|
11
|
+
|
12
|
+
# need to skip this on non-resource controller
|
13
|
+
# > skip_authorize_resource
|
14
|
+
authorize_resource unless: :devise_controller?
|
15
|
+
|
16
|
+
rescue_from CanCan::AccessDenied do |exception|
|
17
|
+
respond_to do |format|
|
18
|
+
format.json { render json: { success: false, error: exception.message }, status: :forbidden }
|
19
|
+
format.html { redirect_to main_app.root_url, alert: exception.message }
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
protected
|
24
|
+
|
25
|
+
def extra_params
|
26
|
+
[] # Override in specific controllers for custom params
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,95 @@
|
|
1
|
+
module Upframework
|
2
|
+
class ResourcesController < ApplicationController
|
3
|
+
before_action :set_base_resource
|
4
|
+
|
5
|
+
def show
|
6
|
+
base_resource
|
7
|
+
|
8
|
+
yield if block_given?
|
9
|
+
render_serialized base_resource
|
10
|
+
end
|
11
|
+
|
12
|
+
def update
|
13
|
+
if base_resource.update(base_resource_params)
|
14
|
+
yield if block_given?
|
15
|
+
render_serialized base_resource
|
16
|
+
else
|
17
|
+
render_errors base_resource.errors.full_messages
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def index
|
22
|
+
base_resource
|
23
|
+
|
24
|
+
yield if block_given?
|
25
|
+
render_serialized base_resource, includes: params[:includes]
|
26
|
+
end
|
27
|
+
|
28
|
+
def create
|
29
|
+
if base_resource.save
|
30
|
+
|
31
|
+
yield if block_given?
|
32
|
+
render_serialized base_resource
|
33
|
+
else
|
34
|
+
render_errors base_resource.errors.full_messages
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def destroy
|
39
|
+
base_resource.destroy
|
40
|
+
head :no_content
|
41
|
+
end
|
42
|
+
|
43
|
+
private
|
44
|
+
|
45
|
+
def base_resource
|
46
|
+
if params[:id]
|
47
|
+
instance_variable_get("@#{base_resource_name}")
|
48
|
+
else
|
49
|
+
instance_variable_get("@#{base_resource_name.pluralize}")
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def set_base_resource
|
54
|
+
data =
|
55
|
+
if params[:id]
|
56
|
+
base_resource_class.find(params[:id])
|
57
|
+
elsif action_name == 'index'
|
58
|
+
base_resource_class.accessible_by(current_ability).where(base_resource_params || {})
|
59
|
+
elsif action_name == 'create'
|
60
|
+
base_resource_class.new(base_resource_params)
|
61
|
+
end
|
62
|
+
|
63
|
+
resource_name = %w[index create].include?(action_name) \
|
64
|
+
? base_resource_name.pluralize \
|
65
|
+
: base_resource_name
|
66
|
+
|
67
|
+
instance_variable_set("@#{resource_name}", data) if data
|
68
|
+
end
|
69
|
+
|
70
|
+
def base_resource_params
|
71
|
+
base_name = base_resource_name
|
72
|
+
|
73
|
+
base_name = base_name.pluralize unless params.key?(base_name)
|
74
|
+
|
75
|
+
params.fetch(base_name).permit(*permitted_columns)
|
76
|
+
end
|
77
|
+
|
78
|
+
def permitted_columns
|
79
|
+
columns = base_resource_class.accessible_fields_by(accessors)
|
80
|
+
columns.concat(extra_params)
|
81
|
+
end
|
82
|
+
|
83
|
+
def accessors
|
84
|
+
current_user
|
85
|
+
end
|
86
|
+
|
87
|
+
def base_resource_name
|
88
|
+
controller_name.singularize
|
89
|
+
end
|
90
|
+
|
91
|
+
def base_resource_class
|
92
|
+
base_resource_name.classify.safe_constantize
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
@@ -1,11 +1,7 @@
|
|
1
1
|
module Upframework
|
2
|
-
class SearchesController <
|
2
|
+
class SearchesController < ApplicationController
|
3
3
|
skip_authorize_resource
|
4
4
|
|
5
|
-
authorize_resource class: :search
|
6
|
-
|
7
|
-
skip_before_action :set_base_resource
|
8
|
-
|
9
5
|
def index
|
10
6
|
args = { current_ability: current_ability, current_user: current_user }
|
11
7
|
args.merge!(permitted_params)
|
@@ -7,17 +7,24 @@ class Upframework::BaseSearch < Upframework::BaseService
|
|
7
7
|
end
|
8
8
|
|
9
9
|
def query(field)
|
10
|
-
@model_scope = yield if
|
10
|
+
@model_scope = yield if field.present?
|
11
11
|
end
|
12
12
|
|
13
13
|
def paginate_scope
|
14
|
+
return if @model_scope.nil?
|
15
|
+
|
14
16
|
@model_scope = @model_scope.
|
15
17
|
page(@page || DEFAULT_PAGE).
|
16
18
|
per(@per_page || DEFAULT_PER_PAGE).
|
17
19
|
order(created_at: :desc)
|
18
20
|
end
|
19
21
|
|
20
|
-
|
21
|
-
|
22
|
+
module ExecuteWrapper
|
23
|
+
def execute
|
24
|
+
super
|
25
|
+
paginate_scope
|
26
|
+
end
|
22
27
|
end
|
28
|
+
|
29
|
+
include ExecuteWrapper
|
23
30
|
end
|
@@ -14,7 +14,7 @@ module Upframework
|
|
14
14
|
|
15
15
|
self.class.send(:attr_reader, *attributes.keys)
|
16
16
|
|
17
|
-
#TODO: Remove.
|
17
|
+
#TODO: Remove. This should be handled on the child class.
|
18
18
|
attributes.each do |key, value|
|
19
19
|
instance_variable_set("@#{key}", value)
|
20
20
|
end
|
data/config/routes.rb
CHANGED
data/lib/upframework.rb
CHANGED
data/lib/upframework/engine.rb
CHANGED
data/lib/upframework/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: upframework
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- jude_cali
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-
|
11
|
+
date: 2020-05-30 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -30,6 +30,34 @@ dependencies:
|
|
30
30
|
- - ">="
|
31
31
|
- !ruby/object:Gem::Version
|
32
32
|
version: 6.0.2.1
|
33
|
+
- !ruby/object:Gem::Dependency
|
34
|
+
name: cancancan
|
35
|
+
requirement: !ruby/object:Gem::Requirement
|
36
|
+
requirements:
|
37
|
+
- - "~>"
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
version: 3.1.0
|
40
|
+
type: :runtime
|
41
|
+
prerelease: false
|
42
|
+
version_requirements: !ruby/object:Gem::Requirement
|
43
|
+
requirements:
|
44
|
+
- - "~>"
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: 3.1.0
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: fast_jsonapi
|
49
|
+
requirement: !ruby/object:Gem::Requirement
|
50
|
+
requirements:
|
51
|
+
- - "~>"
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '1.5'
|
54
|
+
type: :runtime
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
requirements:
|
58
|
+
- - "~>"
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
version: '1.5'
|
33
61
|
description: Rails framework extensions
|
34
62
|
email:
|
35
63
|
- jcalimbas@fullscale.io
|
@@ -46,7 +74,8 @@ files:
|
|
46
74
|
- app/controllers/concerns/upframework/error_handler.rb
|
47
75
|
- app/controllers/concerns/upframework/render_extensions.rb
|
48
76
|
- app/controllers/concerns/upframework/transform_param_keys.rb
|
49
|
-
- app/controllers/upframework/
|
77
|
+
- app/controllers/upframework/api_extensions.rb
|
78
|
+
- app/controllers/upframework/resources_controller.rb
|
50
79
|
- app/controllers/upframework/searches_controller.rb
|
51
80
|
- app/helpers/upframework/application_helper.rb
|
52
81
|
- app/jobs/upframework/application_job.rb
|
@@ -60,7 +89,6 @@ files:
|
|
60
89
|
- lib/tasks/upframework_tasks.rake
|
61
90
|
- lib/upframework.rb
|
62
91
|
- lib/upframework/engine.rb
|
63
|
-
- lib/upframework/searches/routes.rb
|
64
92
|
- lib/upframework/services/routes.rb
|
65
93
|
- lib/upframework/version.rb
|
66
94
|
homepage: https://gitlab.com/disruptors/upframework
|
@@ -1,33 +0,0 @@
|
|
1
|
-
module Upframework
|
2
|
-
class ApiController < ::ApplicationController
|
3
|
-
include ::DeviseTokenAuth::Concerns::SetUserByToken
|
4
|
-
include ::Upframework::ErrorHandler
|
5
|
-
include ::Upframework::TransformParamKeys
|
6
|
-
include ::Upframework::CrudEndpoint
|
7
|
-
include ::Upframework::ServiceEndpoint
|
8
|
-
include ::Upframework::RenderExtensions
|
9
|
-
|
10
|
-
before_action :authenticate!
|
11
|
-
|
12
|
-
# need to skip this on non-resource controller
|
13
|
-
# > skip_authorize_resource
|
14
|
-
authorize_resource
|
15
|
-
|
16
|
-
rescue_from CanCan::AccessDenied do |exception|
|
17
|
-
respond_to do |format|
|
18
|
-
format.json { render json: { success: false, error: exception.message }, status: :forbidden }
|
19
|
-
format.html { redirect_to main_app.root_url, alert: exception.message }
|
20
|
-
end
|
21
|
-
end
|
22
|
-
|
23
|
-
def authenticate!
|
24
|
-
super || authenticate_user!
|
25
|
-
end
|
26
|
-
|
27
|
-
protected
|
28
|
-
|
29
|
-
def extra_params
|
30
|
-
[] # Override in specific controllers for custom params
|
31
|
-
end
|
32
|
-
end
|
33
|
-
end
|
@@ -1,14 +0,0 @@
|
|
1
|
-
module Upframework
|
2
|
-
module Searches
|
3
|
-
module Routes
|
4
|
-
def self.load(namespace: nil, **options)
|
5
|
-
Rails.application.routes.draw do
|
6
|
-
# Create a route for searches
|
7
|
-
# ex.
|
8
|
-
# GET searches
|
9
|
-
get [namespace, "search"].compact.join("/"), to: "searches#index"
|
10
|
-
end
|
11
|
-
end
|
12
|
-
end
|
13
|
-
end
|
14
|
-
end
|