otpor 0.1.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 +7 -0
- data/lib/otpor/active_record_validation_error.rb +22 -0
- data/lib/otpor/json_response.rb +124 -0
- data/lib/otpor/templates/shared/response.json.jbuilder +14 -0
- data/lib/otpor/version.rb +5 -0
- data/lib/otpor.rb +16 -0
- metadata +133 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: d65aa7219b3a7e0218aceb14abc70ffa459989de2421eb8dddf56eb9e902462f
|
4
|
+
data.tar.gz: 491bb18692f97fe0525c01f87ba99a89f78576208b8fa16e2d35eb92d90808e7
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: bedbe5c976532ce83c83ee2e99d864cf9be6f223ac2834d382791128a09022ec4fab145e728c980b819b25900390989a5f66cde56b3587cca37346f2e44cbe81
|
7
|
+
data.tar.gz: 55b496f6d2b6bfb4d56f3a92f7e0456d6741d941cf53764357ae53cbe1f6705d6088df1a0d50b850c43db7b19c13fded9a7c7d37dc862de5d89c725cb33b433e
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module Otpor
|
2
|
+
module ActiveRecordValidationError
|
3
|
+
extend ActiveSupport::Concern
|
4
|
+
|
5
|
+
included do
|
6
|
+
after_validation :log_validation_errors, if: -> { errors.any? }
|
7
|
+
end
|
8
|
+
|
9
|
+
private
|
10
|
+
|
11
|
+
def log_validation_errors
|
12
|
+
error_messages = []
|
13
|
+
errors.each do |error|
|
14
|
+
error_messages << { attribute: error.attribute, message: error.message, type: error.options.dig(:type) || error.type, entity: self.class.name, entity_id: self.id || 'new record'}
|
15
|
+
end
|
16
|
+
return unless error_messages.present?
|
17
|
+
|
18
|
+
RequestStore.store[:errors] ||= error_messages
|
19
|
+
RequestStore.store[:status_symbol] ||= :unprocessable_content
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,124 @@
|
|
1
|
+
module Otpor
|
2
|
+
module JsonResponse
|
3
|
+
extend ActiveSupport::Concern
|
4
|
+
|
5
|
+
included do
|
6
|
+
before_action :capture_initial_instance_variables
|
7
|
+
around_action :rescue_exceptions
|
8
|
+
rescue_from ActionView::MissingTemplate, with: :handle_missing_partial
|
9
|
+
end
|
10
|
+
|
11
|
+
def handle_missing_partial; end
|
12
|
+
|
13
|
+
def default_render(*args)
|
14
|
+
super and return unless request.format.json?
|
15
|
+
|
16
|
+
@errors ||= RequestStore.store[:errors] || nil
|
17
|
+
@notes ||= nil
|
18
|
+
|
19
|
+
@status_symbol = RequestStore.store[:status_symbol] if RequestStore.store[:status_symbol]
|
20
|
+
@status_code = Rack::Utils::SYMBOL_TO_STATUS_CODE[@status_symbol] if @status_symbol
|
21
|
+
@status_code ||= response.status
|
22
|
+
@status = {
|
23
|
+
name: http_status_name(@status_code),
|
24
|
+
code: @status_code,
|
25
|
+
type: http_status_type(@status_code)
|
26
|
+
}
|
27
|
+
|
28
|
+
partial_exists = lookup_context.exists?("#{controller_path}/#{action_name}", [], true)
|
29
|
+
|
30
|
+
@data_partial ||= "#{controller_path}/#{action_name}" if @status[:type].eql?("Success") && partial_exists
|
31
|
+
|
32
|
+
@instance_variables = capture_new_instance_variables
|
33
|
+
|
34
|
+
@meta ||= infer_meta
|
35
|
+
|
36
|
+
render template: "shared/response", formats: :json, status: @status_code
|
37
|
+
end
|
38
|
+
|
39
|
+
private
|
40
|
+
|
41
|
+
def http_status_name(status_code)
|
42
|
+
Rack::Utils::HTTP_STATUS_CODES[status_code]
|
43
|
+
end
|
44
|
+
|
45
|
+
def rescue_exceptions
|
46
|
+
yield
|
47
|
+
rescue StandardError => e
|
48
|
+
@status_code = determine_status_code(e)
|
49
|
+
@status = {
|
50
|
+
name: http_status_name(@status_code),
|
51
|
+
code: @status_code,
|
52
|
+
type: http_status_type(@status_code)
|
53
|
+
}
|
54
|
+
@errors ||= RequestStore.store[:errors] || nil
|
55
|
+
@exception_log = [{ message: e.message, backtrace: e.backtrace[0, 5] }] if Rails.env.development?
|
56
|
+
render template: "shared/response", formats: :json, status: @status_code
|
57
|
+
end
|
58
|
+
|
59
|
+
def determine_status_code(exception)
|
60
|
+
case exception
|
61
|
+
when ActiveRecord::RecordNotFound
|
62
|
+
404
|
63
|
+
when ActionController::RoutingError, ActionController::UnknownFormat
|
64
|
+
404
|
65
|
+
when ActiveRecord::RecordInvalid, ActionController::ParameterMissing
|
66
|
+
422
|
67
|
+
else
|
68
|
+
500
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
def http_status_type(status_code)
|
73
|
+
case status_code
|
74
|
+
when 100..199
|
75
|
+
"Informational"
|
76
|
+
when 200..299
|
77
|
+
"Success"
|
78
|
+
when 300..399
|
79
|
+
"Redirection"
|
80
|
+
when 400..499
|
81
|
+
"Client Error"
|
82
|
+
when 500..599
|
83
|
+
"Server Error"
|
84
|
+
else
|
85
|
+
"Unknown"
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
def capture_initial_instance_variables
|
90
|
+
@initial_instance_variables = instance_variables
|
91
|
+
end
|
92
|
+
|
93
|
+
def capture_new_instance_variables
|
94
|
+
current_instance_variables = instance_variables
|
95
|
+
new_vars = current_instance_variables - @initial_instance_variables
|
96
|
+
new_vars -= %i[@initial_instance_variables @errors @notes @data_partial @status
|
97
|
+
@_response_body @new_instance_variables]
|
98
|
+
new_instance_vars = {}
|
99
|
+
new_vars.each do |var|
|
100
|
+
new_instance_vars[var] = instance_variable_get(var)
|
101
|
+
end
|
102
|
+
new_instance_vars
|
103
|
+
end
|
104
|
+
|
105
|
+
def infer_meta
|
106
|
+
@instance_variables.each do |key, value|
|
107
|
+
next unless value.respond_to?(:total_pages)
|
108
|
+
|
109
|
+
return {
|
110
|
+
pagination: {
|
111
|
+
total_pages: value.total_pages,
|
112
|
+
total_count: value.total_count,
|
113
|
+
current_page: value.current_page,
|
114
|
+
next_page: value.next_page,
|
115
|
+
prev_page: value.prev_page,
|
116
|
+
per_page: value.limit_value
|
117
|
+
}
|
118
|
+
}
|
119
|
+
end
|
120
|
+
|
121
|
+
nil
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
json.status do
|
2
|
+
json.name @status[:name]
|
3
|
+
json.code @status[:code]
|
4
|
+
json.type @status[:type]
|
5
|
+
end
|
6
|
+
|
7
|
+
json.data do
|
8
|
+
json.partial! @data_partial if @data_partial.present?
|
9
|
+
end
|
10
|
+
|
11
|
+
json.errors @errors
|
12
|
+
json.notes @notes
|
13
|
+
json.meta @meta
|
14
|
+
json.exception_log @exception_log
|
data/lib/otpor.rb
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "request_store"
|
4
|
+
require_relative "otpor/version"
|
5
|
+
require_relative "otpor/json_response"
|
6
|
+
require_relative "otpor/active_record_validation_error"
|
7
|
+
|
8
|
+
module Otpor
|
9
|
+
class Engine < ::Rails::Engine
|
10
|
+
initializer "otpor.load_view_paths" do |app|
|
11
|
+
ActiveSupport.on_load(:action_controller) do
|
12
|
+
append_view_path Otpor::Engine.root.join("lib", "otpor", "templates")
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
metadata
ADDED
@@ -0,0 +1,133 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: otpor
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Renan Garcia
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2024-09-21 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rails
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 5.0.0
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 5.0.0
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: kaminari
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 1.2.2
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 1.2.2
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: jbuilder
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: 2.12.0
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: 2.12.0
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: request_store
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '1.7'
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '1.7'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rspec
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: rspec-rails
|
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'
|
97
|
+
description: This gem includes a concern that defines a default Jbuilder template
|
98
|
+
for controller actions that include it, rendering consistent JSON responses.
|
99
|
+
email:
|
100
|
+
- renan.almeida.garcia@icloud.com
|
101
|
+
executables: []
|
102
|
+
extensions: []
|
103
|
+
extra_rdoc_files: []
|
104
|
+
files:
|
105
|
+
- lib/otpor.rb
|
106
|
+
- lib/otpor/active_record_validation_error.rb
|
107
|
+
- lib/otpor/json_response.rb
|
108
|
+
- lib/otpor/templates/shared/response.json.jbuilder
|
109
|
+
- lib/otpor/version.rb
|
110
|
+
homepage: https://github.com/renan-garcia/otpor
|
111
|
+
licenses:
|
112
|
+
- MIT
|
113
|
+
metadata: {}
|
114
|
+
post_install_message:
|
115
|
+
rdoc_options: []
|
116
|
+
require_paths:
|
117
|
+
- lib
|
118
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
119
|
+
requirements:
|
120
|
+
- - ">="
|
121
|
+
- !ruby/object:Gem::Version
|
122
|
+
version: '0'
|
123
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
124
|
+
requirements:
|
125
|
+
- - ">="
|
126
|
+
- !ruby/object:Gem::Version
|
127
|
+
version: '0'
|
128
|
+
requirements: []
|
129
|
+
rubygems_version: 3.5.17
|
130
|
+
signing_key:
|
131
|
+
specification_version: 4
|
132
|
+
summary: 'Otpor: JSON Response Concern'
|
133
|
+
test_files: []
|