cuprum-rails 0.1.0 → 0.2.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 +4 -4
- data/CHANGELOG.md +145 -0
- data/DEVELOPMENT.md +20 -0
- data/README.md +356 -63
- data/lib/cuprum/rails/action.rb +32 -16
- data/lib/cuprum/rails/actions/create.rb +62 -15
- data/lib/cuprum/rails/actions/destroy.rb +23 -7
- data/lib/cuprum/rails/actions/edit.rb +23 -7
- data/lib/cuprum/rails/actions/index.rb +30 -10
- data/lib/cuprum/rails/actions/middleware/associations/cache.rb +112 -0
- data/lib/cuprum/rails/actions/middleware/associations/find.rb +23 -0
- data/lib/cuprum/rails/actions/middleware/associations/parent.rb +70 -0
- data/lib/cuprum/rails/actions/middleware/associations/query.rb +140 -0
- data/lib/cuprum/rails/actions/middleware/associations.rb +12 -0
- data/lib/cuprum/rails/actions/middleware/log_request.rb +126 -0
- data/lib/cuprum/rails/actions/middleware/log_result.rb +51 -0
- data/lib/cuprum/rails/actions/middleware/resources/find.rb +44 -0
- data/lib/cuprum/rails/actions/middleware/resources/query.rb +91 -0
- data/lib/cuprum/rails/actions/middleware/resources.rb +11 -0
- data/lib/cuprum/rails/actions/middleware.rb +13 -0
- data/lib/cuprum/rails/actions/new.rb +16 -4
- data/lib/cuprum/rails/actions/parameter_validation.rb +60 -0
- data/lib/cuprum/rails/actions/resource_action.rb +119 -42
- data/lib/cuprum/rails/actions/show.rb +23 -7
- data/lib/cuprum/rails/actions/update.rb +70 -22
- data/lib/cuprum/rails/actions.rb +11 -7
- data/lib/cuprum/rails/collection.rb +27 -47
- data/lib/cuprum/rails/command.rb +3 -1
- data/lib/cuprum/rails/commands/destroy_one.rb +10 -6
- data/lib/cuprum/rails/commands/find_many.rb +8 -1
- data/lib/cuprum/rails/commands/find_matching.rb +1 -1
- data/lib/cuprum/rails/commands/find_one.rb +8 -0
- data/lib/cuprum/rails/commands/insert_one.rb +17 -6
- data/lib/cuprum/rails/commands/update_one.rb +16 -5
- data/lib/cuprum/rails/constraints/parameters_contract.rb +14 -0
- data/lib/cuprum/rails/constraints.rb +10 -0
- data/lib/cuprum/rails/controller.rb +12 -2
- data/lib/cuprum/rails/controllers/action.rb +100 -0
- data/lib/cuprum/rails/controllers/class_methods/actions.rb +33 -7
- data/lib/cuprum/rails/controllers/class_methods/configuration.rb +36 -0
- data/lib/cuprum/rails/controllers/class_methods/middleware.rb +88 -0
- data/lib/cuprum/rails/controllers/class_methods/validations.rb +2 -2
- data/lib/cuprum/rails/controllers/configuration.rb +41 -1
- data/lib/cuprum/rails/controllers/middleware.rb +59 -0
- data/lib/cuprum/rails/controllers.rb +2 -0
- data/lib/cuprum/rails/errors/invalid_parameters.rb +55 -0
- data/lib/cuprum/rails/errors/invalid_statement.rb +11 -0
- data/lib/cuprum/rails/errors/missing_parameter.rb +42 -0
- data/lib/cuprum/rails/errors/resource_error.rb +46 -0
- data/lib/cuprum/rails/errors.rb +6 -1
- data/lib/cuprum/rails/map_errors.rb +29 -1
- data/lib/cuprum/rails/query.rb +1 -1
- data/lib/cuprum/rails/repository.rb +12 -25
- data/lib/cuprum/rails/request.rb +149 -60
- data/lib/cuprum/rails/resource.rb +119 -85
- data/lib/cuprum/rails/responders/base_responder.rb +78 -0
- data/lib/cuprum/rails/responders/html/plural_resource.rb +9 -39
- data/lib/cuprum/rails/responders/html/rendering.rb +81 -0
- data/lib/cuprum/rails/responders/html/resource.rb +107 -0
- data/lib/cuprum/rails/responders/html/singular_resource.rb +9 -38
- data/lib/cuprum/rails/responders/html.rb +2 -0
- data/lib/cuprum/rails/responders/html_responder.rb +8 -52
- data/lib/cuprum/rails/responders/json/resource.rb +3 -3
- data/lib/cuprum/rails/responders/json_responder.rb +31 -16
- data/lib/cuprum/rails/responders/matching.rb +29 -27
- data/lib/cuprum/rails/responders/serialization.rb +11 -9
- data/lib/cuprum/rails/responders.rb +1 -0
- data/lib/cuprum/rails/responses/head_response.rb +24 -0
- data/lib/cuprum/rails/responses/html/redirect_back_response.rb +55 -0
- data/lib/cuprum/rails/responses/html/redirect_response.rb +19 -4
- data/lib/cuprum/rails/responses/html/render_response.rb +17 -5
- data/lib/cuprum/rails/responses/html.rb +6 -2
- data/lib/cuprum/rails/responses.rb +1 -0
- data/lib/cuprum/rails/result.rb +36 -0
- data/lib/cuprum/rails/routes.rb +36 -23
- data/lib/cuprum/rails/rspec/contract_helpers.rb +57 -0
- data/lib/cuprum/rails/rspec/contracts/action_contracts.rb +754 -0
- data/lib/cuprum/rails/rspec/contracts/actions/create_contracts.rb +289 -0
- data/lib/cuprum/rails/rspec/contracts/actions/destroy_contracts.rb +164 -0
- data/lib/cuprum/rails/rspec/contracts/actions/edit_contracts.rb +73 -0
- data/lib/cuprum/rails/rspec/contracts/actions/index_contracts.rb +108 -0
- data/lib/cuprum/rails/rspec/contracts/actions/new_contracts.rb +111 -0
- data/lib/cuprum/rails/rspec/contracts/actions/show_contracts.rb +72 -0
- data/lib/cuprum/rails/rspec/contracts/actions/update_contracts.rb +263 -0
- data/lib/cuprum/rails/rspec/contracts/actions.rb +8 -0
- data/lib/cuprum/rails/rspec/contracts/command_contracts.rb +479 -0
- data/lib/cuprum/rails/rspec/contracts/responder_contracts.rb +232 -0
- data/lib/cuprum/rails/rspec/contracts/routes_contracts.rb +363 -0
- data/lib/cuprum/rails/rspec/contracts/serializers_contracts.rb +70 -0
- data/lib/cuprum/rails/rspec/contracts.rb +8 -0
- data/lib/cuprum/rails/rspec/matchers/be_a_result_matcher.rb +64 -0
- data/lib/cuprum/rails/rspec/matchers.rb +41 -0
- data/lib/cuprum/rails/serializers/base_serializer.rb +60 -0
- data/lib/cuprum/rails/serializers/context.rb +84 -0
- data/lib/cuprum/rails/serializers/json/active_record_serializer.rb +2 -2
- data/lib/cuprum/rails/serializers/json/array_serializer.rb +9 -8
- data/lib/cuprum/rails/serializers/json/attributes_serializer.rb +95 -172
- data/lib/cuprum/rails/serializers/json/error_serializer.rb +2 -2
- data/lib/cuprum/rails/serializers/json/hash_serializer.rb +9 -8
- data/lib/cuprum/rails/serializers/json/identity_serializer.rb +3 -3
- data/lib/cuprum/rails/serializers/json/properties_serializer.rb +252 -0
- data/lib/cuprum/rails/serializers/json.rb +2 -1
- data/lib/cuprum/rails/serializers.rb +3 -1
- data/lib/cuprum/rails/version.rb +1 -1
- data/lib/cuprum/rails.rb +19 -16
- metadata +73 -131
- data/lib/cuprum/rails/controller_action.rb +0 -121
- data/lib/cuprum/rails/errors/missing_parameters.rb +0 -33
- data/lib/cuprum/rails/errors/missing_primary_key.rb +0 -46
- data/lib/cuprum/rails/errors/undefined_permitted_attributes.rb +0 -34
- data/lib/cuprum/rails/rspec/command_contract.rb +0 -460
- data/lib/cuprum/rails/rspec/define_route_contract.rb +0 -84
- data/lib/cuprum/rails/serializers/json/serializer.rb +0 -66
@@ -0,0 +1,81 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'cuprum/rails/responders/html'
|
4
|
+
|
5
|
+
module Cuprum::Rails::Responders::Html
|
6
|
+
# Implements generating HTML response objects.
|
7
|
+
module Rendering
|
8
|
+
# Creates a HeadResponse based on the given HTTP status.
|
9
|
+
#
|
10
|
+
# @param status [Integer] the HTTP status of the response.
|
11
|
+
#
|
12
|
+
# @return [Cuprum::Rails::Responses::HeadResponse] the response.
|
13
|
+
def head(status:)
|
14
|
+
Cuprum::Rails::Responses::HeadResponse.new(status: status)
|
15
|
+
end
|
16
|
+
|
17
|
+
# Creates a RedirectBackResponse based on the given HTTP status.
|
18
|
+
#
|
19
|
+
# @param fallback_location [String] the path or url to redirect to if the
|
20
|
+
# previous location cannot be determined.
|
21
|
+
# @param flash [Hash] the flash messages to set.
|
22
|
+
# @param status [Integer] the HTTP status of the response.
|
23
|
+
def redirect_back(fallback_location: '/', flash: {}, status: 302)
|
24
|
+
Cuprum::Rails::Responses::Html::RedirectBackResponse
|
25
|
+
.new(fallback_location: fallback_location, flash: flash, status: status)
|
26
|
+
end
|
27
|
+
|
28
|
+
# Creates a RedirectResponse based on the given path and HTTP status.
|
29
|
+
#
|
30
|
+
# @param flash [Hash] the flash messages to set.
|
31
|
+
# @param path [String] the path or url to redirect to.
|
32
|
+
# @param status [Integer] the HTTP status of the response.
|
33
|
+
#
|
34
|
+
# @return [Cuprum::Rails::Responses::Html::RedirectResponse] the response.
|
35
|
+
def redirect_to(path, flash: {}, status: 302)
|
36
|
+
Cuprum::Rails::Responses::Html::RedirectResponse
|
37
|
+
.new(path, flash: flash, status: status)
|
38
|
+
end
|
39
|
+
|
40
|
+
# Creates a RenderResponse based on the given template and parameters.
|
41
|
+
#
|
42
|
+
# @param assigns [Hash] variables to assign when rendering the template.
|
43
|
+
# @param flash [Hash] the flash messages to set.
|
44
|
+
# @param layout [String] the layout to render.
|
45
|
+
# @param status [Integer] the HTTP status of the response.
|
46
|
+
# @param template [String, Symbol] the template to render.
|
47
|
+
#
|
48
|
+
# @return [Cuprum::Rails::Responses::Html::RenderResponse] the response.
|
49
|
+
def render(template, assigns: nil, flash: {}, layout: nil, status: 200)
|
50
|
+
Cuprum::Rails::Responses::Html::RenderResponse.new(
|
51
|
+
template,
|
52
|
+
assigns: assigns || default_assigns,
|
53
|
+
flash: flash,
|
54
|
+
layout: layout,
|
55
|
+
status: status
|
56
|
+
)
|
57
|
+
end
|
58
|
+
|
59
|
+
private
|
60
|
+
|
61
|
+
def default_assigns
|
62
|
+
return nil if result.nil?
|
63
|
+
|
64
|
+
assigns = default_value
|
65
|
+
|
66
|
+
assigns[:error] = result.error unless result.error.nil?
|
67
|
+
|
68
|
+
assigns
|
69
|
+
end
|
70
|
+
|
71
|
+
def default_value
|
72
|
+
if result.value.is_a?(Hash)
|
73
|
+
result.value
|
74
|
+
elsif !result.value.nil?
|
75
|
+
{ value: result.value }
|
76
|
+
else
|
77
|
+
{}
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
@@ -0,0 +1,107 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'cuprum/collections/errors/failed_validation'
|
4
|
+
|
5
|
+
require 'cuprum/rails/responders/html'
|
6
|
+
require 'cuprum/rails/responders/html_responder'
|
7
|
+
|
8
|
+
module Cuprum::Rails::Responders::Html
|
9
|
+
# Defines default responses for a RESTful resource.
|
10
|
+
#
|
11
|
+
# If the resource is plural:
|
12
|
+
#
|
13
|
+
# - #create failure: renders the :new template.
|
14
|
+
# - #create success: redirects to the resource #show page.
|
15
|
+
# - #destroy success: redirects to the resource #index page.
|
16
|
+
# - #index failure: redirects to the root path.
|
17
|
+
# - #update failure: renders the :edit template.
|
18
|
+
# - #update success: redirects to the resource #show page.
|
19
|
+
#
|
20
|
+
# If the resource is singular:
|
21
|
+
#
|
22
|
+
# - #create failure: renders the :new template.
|
23
|
+
# - #create success: redirects to the resource #show page.
|
24
|
+
# - #destroy success: redirects to the parent resource.
|
25
|
+
# - #update failure: renders the :edit template.
|
26
|
+
# - #update success: redirects to the resource #show page.
|
27
|
+
#
|
28
|
+
# Responds to any other successful result by rendering the template for the
|
29
|
+
# action name and passing the result value as assigned variables. For a
|
30
|
+
# failing result, redirects to the parent resource (for a singular resource),
|
31
|
+
# or redirects to either the show page or the index page for the resource.
|
32
|
+
class Resource < Cuprum::Rails::Responders::HtmlResponder
|
33
|
+
action :create do
|
34
|
+
match :failure, error: Cuprum::Collections::Errors::FailedValidation do
|
35
|
+
render :new,
|
36
|
+
assigns: result.value.merge(errors: result.error.errors),
|
37
|
+
status: 422 # rubocop:disable Rails/HttpStatus
|
38
|
+
end
|
39
|
+
|
40
|
+
match :success do
|
41
|
+
next redirect_to(routes.show_path) if resource.singular?
|
42
|
+
|
43
|
+
entity = result.value[resource.singular_name]
|
44
|
+
|
45
|
+
redirect_to routes.show_path(entity)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
action :destroy do
|
50
|
+
match :success do
|
51
|
+
next redirect_to(routes.parent_path) if resource.singular?
|
52
|
+
|
53
|
+
redirect_to(routes.index_path)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
action :index do
|
58
|
+
match :failure do
|
59
|
+
redirect_to routes.root_path
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
action :update do
|
64
|
+
match :failure, error: Cuprum::Collections::Errors::FailedValidation do
|
65
|
+
render :edit,
|
66
|
+
assigns: result.value.merge(errors: result.error.errors),
|
67
|
+
status: 422 # rubocop:disable Rails/HttpStatus
|
68
|
+
end
|
69
|
+
|
70
|
+
match :success do
|
71
|
+
next redirect_to(routes.show_path) if resource.singular?
|
72
|
+
|
73
|
+
entity = result.value[resource.singular_name]
|
74
|
+
|
75
|
+
redirect_to routes.show_path(entity)
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
match :failure, error: Cuprum::Collections::Errors::NotFound do |result|
|
80
|
+
handle_not_found_error(result)
|
81
|
+
end
|
82
|
+
|
83
|
+
match :failure do
|
84
|
+
next redirect_to(routes.show_path) if resource.singular?
|
85
|
+
|
86
|
+
redirect_to(routes.index_path)
|
87
|
+
end
|
88
|
+
|
89
|
+
private
|
90
|
+
|
91
|
+
def find_ancestor(&block)
|
92
|
+
resource.each_ancestor.find(&block)
|
93
|
+
end
|
94
|
+
|
95
|
+
def handle_not_found_error(result)
|
96
|
+
matching = find_ancestor do |ancestor|
|
97
|
+
ancestor.name == result.error.collection_name
|
98
|
+
end
|
99
|
+
|
100
|
+
return render(request.action_name, status: 404) unless matching # rubocop:disable Rails/HttpStatus
|
101
|
+
|
102
|
+
routes = matching.routes.with_wildcards(request.path_params || {})
|
103
|
+
|
104
|
+
redirect_to(matching.singular? ? routes.show_path : routes.index_path)
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
@@ -3,7 +3,7 @@
|
|
3
3
|
require 'cuprum/collections/errors/failed_validation'
|
4
4
|
|
5
5
|
require 'cuprum/rails/responders/html'
|
6
|
-
require 'cuprum/rails/responders/
|
6
|
+
require 'cuprum/rails/responders/html/resource'
|
7
7
|
|
8
8
|
module Cuprum::Rails::Responders::Html
|
9
9
|
# Defines default responses for a singular RESTful resource.
|
@@ -17,43 +17,14 @@ module Cuprum::Rails::Responders::Html
|
|
17
17
|
# Responds to any other successful result by rendering the template for the
|
18
18
|
# action name and passing the result value as assigned variables. For a
|
19
19
|
# failing result, redirects to the parent resource.
|
20
|
-
class SingularResource < Cuprum::Rails::Responders::
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
match :success do
|
29
|
-
redirect_to resource.routes.show_path
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
|
-
action :destroy do
|
34
|
-
match :success do
|
35
|
-
next redirect_to(resource.base_path) unless resource.routes
|
36
|
-
|
37
|
-
redirect_to(resource.routes.parent_path)
|
38
|
-
end
|
39
|
-
end
|
40
|
-
|
41
|
-
action :update do
|
42
|
-
match :failure, error: Cuprum::Collections::Errors::FailedValidation do
|
43
|
-
render :edit,
|
44
|
-
assigns: result.value.merge(errors: result.error.errors),
|
45
|
-
status: 422 # rubocop:disable Rails/HttpStatus
|
46
|
-
end
|
47
|
-
|
48
|
-
match :success do
|
49
|
-
redirect_to resource.routes.show_path
|
50
|
-
end
|
51
|
-
end
|
52
|
-
|
53
|
-
match :failure do
|
54
|
-
next redirect_to(resource.base_path) unless resource.routes
|
55
|
-
|
56
|
-
redirect_to(resource.routes.parent_path)
|
20
|
+
class SingularResource < Cuprum::Rails::Responders::Html::Resource
|
21
|
+
def initialize(**options)
|
22
|
+
super
|
23
|
+
|
24
|
+
SleepingKingStudios::Tools::CoreTools.deprecate(
|
25
|
+
'Cuprum::Rails::Responders::Html::SingularResource',
|
26
|
+
message: 'use Cuprum::Rails::Responders::Html::Resource'
|
27
|
+
)
|
57
28
|
end
|
58
29
|
end
|
59
30
|
end
|
@@ -6,6 +6,8 @@ module Cuprum::Rails::Responders
|
|
6
6
|
# Namespace for HTML responders, which process action results into responses.
|
7
7
|
module Html
|
8
8
|
autoload :PluralResource, 'cuprum/rails/responders/html/plural_resource'
|
9
|
+
autoload :Rendering, 'cuprum/rails/responders/html/rendering'
|
10
|
+
autoload :Resource, 'cuprum/rails/responders/html/resource'
|
9
11
|
autoload :SingularResource, 'cuprum/rails/responders/html/singular_resource'
|
10
12
|
end
|
11
13
|
end
|
@@ -3,6 +3,8 @@
|
|
3
3
|
require 'cuprum/rails/responses/html/redirect_response'
|
4
4
|
require 'cuprum/rails/responders'
|
5
5
|
require 'cuprum/rails/responders/actions'
|
6
|
+
require 'cuprum/rails/responders/base_responder'
|
7
|
+
require 'cuprum/rails/responders/html/rendering'
|
6
8
|
require 'cuprum/rails/responders/matching'
|
7
9
|
|
8
10
|
module Cuprum::Rails::Responders
|
@@ -35,7 +37,8 @@ module Cuprum::Rails::Responders
|
|
35
37
|
#
|
36
38
|
# @see Cuprum::Rails::Responders::Actions::ClassMethods#action
|
37
39
|
# @see Cuprum::Rails::Responders::Matching::ClassMethods#match
|
38
|
-
class HtmlResponder
|
40
|
+
class HtmlResponder < BaseResponder
|
41
|
+
include Cuprum::Rails::Responders::Html::Rendering
|
39
42
|
include Cuprum::Rails::Responders::Matching
|
40
43
|
include Cuprum::Rails::Responders::Actions
|
41
44
|
|
@@ -59,71 +62,24 @@ module Cuprum::Rails::Responders
|
|
59
62
|
:html
|
60
63
|
end
|
61
64
|
|
62
|
-
# Creates a RedirectResponse based on the given path and HTTP status.
|
63
|
-
#
|
64
|
-
# @param path [String] The path or url to redirect to.
|
65
|
-
# @param status [Integer] The HTTP status of the response.
|
66
|
-
#
|
67
|
-
# @return [Cuprum::Rails::Responses::Html::RedirectResponse] the response.
|
68
|
-
def redirect_to(path, status: 302)
|
69
|
-
Cuprum::Rails::Responses::Html::RedirectResponse.new(path, status: status)
|
70
|
-
end
|
71
|
-
|
72
|
-
# Creates a RenderResponse based on the given template and parameters.
|
73
|
-
#
|
74
|
-
# @param assigns [Hash] Variables to assign when rendering the template.
|
75
|
-
# @param layout [String] The layout to render.
|
76
|
-
# @param status [Integer] The HTTP status of the response.
|
77
|
-
# @param template [String, Symbol] The template to render.
|
78
|
-
#
|
79
|
-
# @return [Cuprum::Rails::Responses::Html::RenderResponse] the response.
|
80
|
-
def render(template, assigns: nil, layout: nil, status: 200)
|
81
|
-
Cuprum::Rails::Responses::Html::RenderResponse.new(
|
82
|
-
template,
|
83
|
-
assigns: assigns || default_assigns,
|
84
|
-
layout: layout,
|
85
|
-
status: status
|
86
|
-
)
|
87
|
-
end
|
88
|
-
|
89
65
|
private
|
90
66
|
|
91
|
-
def default_assigns
|
92
|
-
return nil if result.nil?
|
93
|
-
|
94
|
-
assigns = default_value
|
95
|
-
|
96
|
-
assigns[:error] = result.error unless result.error.nil?
|
97
|
-
|
98
|
-
assigns
|
99
|
-
end
|
100
|
-
|
101
|
-
def default_value
|
102
|
-
if result.value.is_a?(Hash)
|
103
|
-
result.value
|
104
|
-
elsif !result.value.nil?
|
105
|
-
{ value: result.value }
|
106
|
-
else
|
107
|
-
{}
|
108
|
-
end
|
109
|
-
end
|
110
|
-
|
111
67
|
def resource_entity
|
112
68
|
if result.value.is_a?(Hash)
|
113
|
-
result.value[resource.
|
69
|
+
result.value[resource.singular_name]
|
114
70
|
else
|
115
71
|
result.value
|
116
72
|
end
|
117
73
|
end
|
118
74
|
|
119
75
|
def resource_path(result)
|
120
|
-
return
|
76
|
+
return routes.index_path if result.value.nil?
|
121
77
|
|
122
78
|
entity = resource_entity
|
123
79
|
|
124
|
-
return
|
80
|
+
return routes.show_path(entity) if entity
|
125
81
|
|
126
|
-
|
82
|
+
routes.index_path
|
127
83
|
end
|
128
84
|
end
|
129
85
|
end
|
@@ -5,7 +5,7 @@ require 'cuprum/collections/errors/extra_attributes'
|
|
5
5
|
require 'cuprum/collections/errors/failed_validation'
|
6
6
|
require 'cuprum/collections/errors/not_found'
|
7
7
|
|
8
|
-
require 'cuprum/rails/errors/
|
8
|
+
require 'cuprum/rails/errors/invalid_parameters'
|
9
9
|
require 'cuprum/rails/responders/json'
|
10
10
|
require 'cuprum/rails/responders/json_responder'
|
11
11
|
|
@@ -19,7 +19,7 @@ module Cuprum::Rails::Responders::Json
|
|
19
19
|
# Unprocessable Entity.
|
20
20
|
# - failure FailedValidation: serializes the error with status 422
|
21
21
|
# Unprocessable Entity.
|
22
|
-
# - failure
|
22
|
+
# - failure InvalidParameters: serializes the error with status 400 Bad
|
23
23
|
# Request.
|
24
24
|
# - failure NotFound: serializes the error with status 404 Not Found.
|
25
25
|
#
|
@@ -53,7 +53,7 @@ module Cuprum::Rails::Responders::Json
|
|
53
53
|
render_failure(result.error, status: 404)
|
54
54
|
end
|
55
55
|
|
56
|
-
match :failure, error: Cuprum::Rails::Errors::
|
56
|
+
match :failure, error: Cuprum::Rails::Errors::InvalidParameters do |result|
|
57
57
|
render_failure(result.error, status: 400)
|
58
58
|
end
|
59
59
|
end
|
@@ -2,9 +2,11 @@
|
|
2
2
|
|
3
3
|
require 'cuprum/rails/responders'
|
4
4
|
require 'cuprum/rails/responders/actions'
|
5
|
+
require 'cuprum/rails/responders/base_responder'
|
5
6
|
require 'cuprum/rails/responders/matching'
|
6
7
|
require 'cuprum/rails/responders/serialization'
|
7
8
|
require 'cuprum/rails/responses/json_response'
|
9
|
+
require 'cuprum/rails/serializers/base_serializer'
|
8
10
|
require 'cuprum/rails/serializers/json'
|
9
11
|
|
10
12
|
module Cuprum::Rails::Responders
|
@@ -32,7 +34,7 @@ module Cuprum::Rails::Responders
|
|
32
34
|
# render_failure(error, status: 403)
|
33
35
|
# end
|
34
36
|
# end
|
35
|
-
class JsonResponder
|
37
|
+
class JsonResponder < BaseResponder
|
36
38
|
include Cuprum::Rails::Responders::Matching
|
37
39
|
include Cuprum::Rails::Responders::Actions
|
38
40
|
include Cuprum::Rails::Responders::Serialization
|
@@ -46,31 +48,39 @@ module Cuprum::Rails::Responders
|
|
46
48
|
render_success(result.value)
|
47
49
|
end
|
48
50
|
|
49
|
-
match :failure do
|
50
|
-
render_failure(
|
51
|
+
match :failure do |result|
|
52
|
+
render_failure(Rails.env.development? ? result.error : generic_error)
|
51
53
|
end
|
52
54
|
|
53
|
-
# @param action_name [String, Symbol]
|
54
|
-
# @param
|
55
|
+
# @param action_name [String, Symbol] the name of the action to match.
|
56
|
+
# @param controller [Cuprum::Rails::Controller] the called controller.
|
57
|
+
# @param controller_name [String] the name of the called controller.
|
58
|
+
# Defaults to controller.class.name.
|
59
|
+
# @param matcher [Cuprum::Matcher] an optional matcher specific to the
|
55
60
|
# action. This will be matched before any of the generic matchers.
|
56
|
-
# @param member_action [Boolean]
|
61
|
+
# @param member_action [Boolean] true if the action acts on a collection
|
57
62
|
# item, not on the collection as a whole.
|
58
|
-
# @param
|
63
|
+
# @param request [Cuprum::Rails::Request] the request to the controller.
|
64
|
+
# @param serializers [Hash<Class, Object>] the serializers for converting
|
65
|
+
# result values into serialized data.
|
66
|
+
# @param options [Hash] additional parameters for the responder.
|
59
67
|
def initialize( # rubocop:disable Metrics/ParameterLists
|
60
68
|
action_name:,
|
61
|
-
|
69
|
+
controller:,
|
70
|
+
request:,
|
62
71
|
serializers:,
|
63
|
-
matcher: nil,
|
64
72
|
member_action: false,
|
65
|
-
**
|
73
|
+
**options
|
66
74
|
)
|
67
75
|
super(
|
68
|
-
action_name:
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
76
|
+
action_name: action_name,
|
77
|
+
controller: controller,
|
78
|
+
matcher: matcher,
|
79
|
+
member_action: member_action,
|
80
|
+
resource: resource,
|
81
|
+
request: request,
|
82
|
+
serializers: serializers,
|
83
|
+
**options
|
74
84
|
)
|
75
85
|
end
|
76
86
|
|
@@ -82,6 +92,11 @@ module Cuprum::Rails::Responders
|
|
82
92
|
:json
|
83
93
|
end
|
84
94
|
|
95
|
+
# @return [Cuprum::Error] a generic error for generating failure responses.
|
96
|
+
def generic_error
|
97
|
+
GENERIC_ERROR
|
98
|
+
end
|
99
|
+
|
85
100
|
# Creates a JsonResponse based on the given data and options.
|
86
101
|
#
|
87
102
|
# @param json [Object] The data to serialize.
|
@@ -46,44 +46,45 @@ module Cuprum::Rails::Responders
|
|
46
46
|
attr_reader :matcher
|
47
47
|
end
|
48
48
|
|
49
|
-
|
50
|
-
|
51
|
-
|
49
|
+
class << self
|
50
|
+
private
|
51
|
+
|
52
|
+
def included(other)
|
53
|
+
super
|
52
54
|
|
53
|
-
|
55
|
+
other.extend(ClassMethods)
|
56
|
+
end
|
54
57
|
end
|
55
58
|
|
56
|
-
# @param action_name [String, Symbol]
|
57
|
-
# @param
|
59
|
+
# @param action_name [String, Symbol] the name of the action to match.
|
60
|
+
# @param controller [Cuprum::Rails::Controller] the called controller.
|
61
|
+
# @param matcher [Cuprum::Matcher] an optional matcher specific to the
|
58
62
|
# action. This will be matched before any of the generic matchers.
|
59
|
-
# @param member_action [Boolean]
|
63
|
+
# @param member_action [Boolean] true if the action acts on a collection
|
60
64
|
# item, not on the collection as a whole.
|
61
|
-
# @param
|
62
|
-
def initialize(
|
65
|
+
# @param request [Cuprum::Rails::Request] the request to the controller.
|
66
|
+
def initialize( # rubocop:disable Metrics/ParameterLists
|
63
67
|
action_name:,
|
64
|
-
|
65
|
-
|
68
|
+
controller:,
|
69
|
+
request:,
|
70
|
+
matcher: nil,
|
66
71
|
member_action: false,
|
67
|
-
**
|
72
|
+
**options
|
68
73
|
)
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
74
|
+
super(
|
75
|
+
action_name: action_name,
|
76
|
+
controller: controller,
|
77
|
+
member_action: member_action,
|
78
|
+
request: request,
|
79
|
+
**options
|
80
|
+
)
|
81
|
+
|
82
|
+
@matcher = matcher
|
73
83
|
end
|
74
84
|
|
75
|
-
# @return [String, Symbol] the name of the action to match.
|
76
|
-
attr_reader :action_name
|
77
|
-
|
78
85
|
# @return [Cuprum::Matcher] an optional matcher specific to the action.
|
79
86
|
attr_reader :matcher
|
80
87
|
|
81
|
-
# @return [Cuprum::Rails::Resource] the resource for the controller.
|
82
|
-
attr_reader :resource
|
83
|
-
|
84
|
-
# @return [Cuprum::Result] the result of calling the action.
|
85
|
-
attr_reader :result
|
86
|
-
|
87
88
|
# Finds and calls the response clause that matches the given result.
|
88
89
|
#
|
89
90
|
# 1. Checks for an exact match (the result status, value, and error all
|
@@ -96,8 +97,9 @@ module Cuprum::Rails::Responders
|
|
96
97
|
# error or a value.
|
97
98
|
# 4. If there is no matching response clause, raises an exception.
|
98
99
|
#
|
99
|
-
# @
|
100
|
-
#
|
100
|
+
# @param result [Cuprum::Result] the result of the action call.
|
101
|
+
#
|
102
|
+
# @return [#call] the response object from the matching response clause.
|
101
103
|
#
|
102
104
|
# @raise [Cuprum::Matching::NoMatchError] if none of the response clauses
|
103
105
|
# match the result.
|
@@ -1,25 +1,21 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'cuprum/rails/responders'
|
4
|
+
require 'cuprum/rails/serializers/base_serializer'
|
5
|
+
require 'cuprum/rails/serializers/context'
|
4
6
|
|
5
7
|
module Cuprum::Rails::Responders
|
6
8
|
# Implements serializing a result value into response data.
|
7
9
|
module Serialization
|
8
|
-
# @param root_serializer [Class] The root serializer for serializing the
|
9
|
-
# result value.
|
10
10
|
# @param serializers [Hash<Class, Object>] The serializers for converting
|
11
11
|
# result values into serialized data.
|
12
12
|
# @param options [Hash] Additional parameters for the responder.
|
13
|
-
def initialize(
|
13
|
+
def initialize(serializers:, **options)
|
14
14
|
super(**options)
|
15
15
|
|
16
|
-
@
|
17
|
-
@serializers = serializers
|
16
|
+
@serializers = serializers
|
18
17
|
end
|
19
18
|
|
20
|
-
# @return [Object] the root serializer for serializing the result value.
|
21
|
-
attr_reader :root_serializer
|
22
|
-
|
23
19
|
# @return [Hash<Class, Object>] The serializers for converting result values
|
24
20
|
# into serialized data.
|
25
21
|
attr_reader :serializers
|
@@ -30,7 +26,13 @@ module Cuprum::Rails::Responders
|
|
30
26
|
#
|
31
27
|
# @return [Object] the serialized data.
|
32
28
|
def serialize(object)
|
33
|
-
|
29
|
+
context = Cuprum::Rails::Serializers::Context.new(
|
30
|
+
serializers: serializers
|
31
|
+
)
|
32
|
+
|
33
|
+
Cuprum::Rails::Serializers::BaseSerializer
|
34
|
+
.instance
|
35
|
+
.call(object, context: context)
|
34
36
|
end
|
35
37
|
end
|
36
38
|
end
|
@@ -6,6 +6,7 @@ module Cuprum::Rails
|
|
6
6
|
# Namespace for responders, which process action results into responses.
|
7
7
|
module Responders
|
8
8
|
autoload :Actions, 'cuprum/rails/responders/actions'
|
9
|
+
autoload :BaseResponder, 'cuprum/rails/responders/base_responder'
|
9
10
|
autoload :Html, 'cuprum/rails/responders/html'
|
10
11
|
autoload :HtmlResponder, 'cuprum/rails/responders/html_responder'
|
11
12
|
autoload :Json, 'cuprum/rails/responders/json'
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'cuprum/rails/responses'
|
4
|
+
|
5
|
+
module Cuprum::Rails::Responses
|
6
|
+
# Encapsulates a response without a response body.
|
7
|
+
class HeadResponse
|
8
|
+
# @param status [Integer] the HTTP status of the response.
|
9
|
+
def initialize(status:)
|
10
|
+
@status = status
|
11
|
+
end
|
12
|
+
|
13
|
+
# @return [Integer] the HTTP status of the response.
|
14
|
+
attr_reader :status
|
15
|
+
|
16
|
+
# Calls the renderer's #head method with the configured status.
|
17
|
+
#
|
18
|
+
# @param renderer [#render] The context for executing the response, such as
|
19
|
+
# a Rails controller.
|
20
|
+
def call(renderer)
|
21
|
+
renderer.head(status)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'cuprum/rails/responses/html'
|
4
|
+
|
5
|
+
module Cuprum::Rails::Responses::Html
|
6
|
+
# Encapsulates an HTML response that redirects to the previous path.
|
7
|
+
class RedirectBackResponse
|
8
|
+
# @param fallback_location [String] the path or url to redirect to if the
|
9
|
+
# previous location cannot be determined.
|
10
|
+
# @param flash [Hash] the flash messages to set.
|
11
|
+
# @param status [Integer] the HTTP status of the response.
|
12
|
+
def initialize(fallback_location: '/', flash: {}, status: 302)
|
13
|
+
@fallback_location = fallback_location
|
14
|
+
@flash = flash
|
15
|
+
@status = status
|
16
|
+
end
|
17
|
+
|
18
|
+
# @return [String] the path or url to redirect to if the previous location
|
19
|
+
# cannot be determined.
|
20
|
+
attr_reader :fallback_location
|
21
|
+
|
22
|
+
# @return [Hash] the flash messages to set.
|
23
|
+
attr_reader :flash
|
24
|
+
|
25
|
+
# @return [Integer] the HTTP status of the response.
|
26
|
+
attr_reader :status
|
27
|
+
|
28
|
+
# Calls the renderer's #redirect_back_or_to method with the status.
|
29
|
+
#
|
30
|
+
# @param renderer [#redirect_back_or_to] the context for executing the
|
31
|
+
# response, such as a Rails controller.
|
32
|
+
def call(renderer)
|
33
|
+
assign_flash(renderer)
|
34
|
+
|
35
|
+
# :nocov:
|
36
|
+
if Rails.version >= '7.0' # @todo Rails 6
|
37
|
+
renderer.redirect_back_or_to(fallback_location, status: status)
|
38
|
+
else
|
39
|
+
renderer.redirect_back(
|
40
|
+
fallback_location: fallback_location,
|
41
|
+
status: status
|
42
|
+
)
|
43
|
+
end
|
44
|
+
# :nocov:
|
45
|
+
end
|
46
|
+
|
47
|
+
private
|
48
|
+
|
49
|
+
def assign_flash(renderer)
|
50
|
+
flash.each do |key, value|
|
51
|
+
renderer.flash[key] = value
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|