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.
Files changed (113) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +145 -0
  3. data/DEVELOPMENT.md +20 -0
  4. data/README.md +356 -63
  5. data/lib/cuprum/rails/action.rb +32 -16
  6. data/lib/cuprum/rails/actions/create.rb +62 -15
  7. data/lib/cuprum/rails/actions/destroy.rb +23 -7
  8. data/lib/cuprum/rails/actions/edit.rb +23 -7
  9. data/lib/cuprum/rails/actions/index.rb +30 -10
  10. data/lib/cuprum/rails/actions/middleware/associations/cache.rb +112 -0
  11. data/lib/cuprum/rails/actions/middleware/associations/find.rb +23 -0
  12. data/lib/cuprum/rails/actions/middleware/associations/parent.rb +70 -0
  13. data/lib/cuprum/rails/actions/middleware/associations/query.rb +140 -0
  14. data/lib/cuprum/rails/actions/middleware/associations.rb +12 -0
  15. data/lib/cuprum/rails/actions/middleware/log_request.rb +126 -0
  16. data/lib/cuprum/rails/actions/middleware/log_result.rb +51 -0
  17. data/lib/cuprum/rails/actions/middleware/resources/find.rb +44 -0
  18. data/lib/cuprum/rails/actions/middleware/resources/query.rb +91 -0
  19. data/lib/cuprum/rails/actions/middleware/resources.rb +11 -0
  20. data/lib/cuprum/rails/actions/middleware.rb +13 -0
  21. data/lib/cuprum/rails/actions/new.rb +16 -4
  22. data/lib/cuprum/rails/actions/parameter_validation.rb +60 -0
  23. data/lib/cuprum/rails/actions/resource_action.rb +119 -42
  24. data/lib/cuprum/rails/actions/show.rb +23 -7
  25. data/lib/cuprum/rails/actions/update.rb +70 -22
  26. data/lib/cuprum/rails/actions.rb +11 -7
  27. data/lib/cuprum/rails/collection.rb +27 -47
  28. data/lib/cuprum/rails/command.rb +3 -1
  29. data/lib/cuprum/rails/commands/destroy_one.rb +10 -6
  30. data/lib/cuprum/rails/commands/find_many.rb +8 -1
  31. data/lib/cuprum/rails/commands/find_matching.rb +1 -1
  32. data/lib/cuprum/rails/commands/find_one.rb +8 -0
  33. data/lib/cuprum/rails/commands/insert_one.rb +17 -6
  34. data/lib/cuprum/rails/commands/update_one.rb +16 -5
  35. data/lib/cuprum/rails/constraints/parameters_contract.rb +14 -0
  36. data/lib/cuprum/rails/constraints.rb +10 -0
  37. data/lib/cuprum/rails/controller.rb +12 -2
  38. data/lib/cuprum/rails/controllers/action.rb +100 -0
  39. data/lib/cuprum/rails/controllers/class_methods/actions.rb +33 -7
  40. data/lib/cuprum/rails/controllers/class_methods/configuration.rb +36 -0
  41. data/lib/cuprum/rails/controllers/class_methods/middleware.rb +88 -0
  42. data/lib/cuprum/rails/controllers/class_methods/validations.rb +2 -2
  43. data/lib/cuprum/rails/controllers/configuration.rb +41 -1
  44. data/lib/cuprum/rails/controllers/middleware.rb +59 -0
  45. data/lib/cuprum/rails/controllers.rb +2 -0
  46. data/lib/cuprum/rails/errors/invalid_parameters.rb +55 -0
  47. data/lib/cuprum/rails/errors/invalid_statement.rb +11 -0
  48. data/lib/cuprum/rails/errors/missing_parameter.rb +42 -0
  49. data/lib/cuprum/rails/errors/resource_error.rb +46 -0
  50. data/lib/cuprum/rails/errors.rb +6 -1
  51. data/lib/cuprum/rails/map_errors.rb +29 -1
  52. data/lib/cuprum/rails/query.rb +1 -1
  53. data/lib/cuprum/rails/repository.rb +12 -25
  54. data/lib/cuprum/rails/request.rb +149 -60
  55. data/lib/cuprum/rails/resource.rb +119 -85
  56. data/lib/cuprum/rails/responders/base_responder.rb +78 -0
  57. data/lib/cuprum/rails/responders/html/plural_resource.rb +9 -39
  58. data/lib/cuprum/rails/responders/html/rendering.rb +81 -0
  59. data/lib/cuprum/rails/responders/html/resource.rb +107 -0
  60. data/lib/cuprum/rails/responders/html/singular_resource.rb +9 -38
  61. data/lib/cuprum/rails/responders/html.rb +2 -0
  62. data/lib/cuprum/rails/responders/html_responder.rb +8 -52
  63. data/lib/cuprum/rails/responders/json/resource.rb +3 -3
  64. data/lib/cuprum/rails/responders/json_responder.rb +31 -16
  65. data/lib/cuprum/rails/responders/matching.rb +29 -27
  66. data/lib/cuprum/rails/responders/serialization.rb +11 -9
  67. data/lib/cuprum/rails/responders.rb +1 -0
  68. data/lib/cuprum/rails/responses/head_response.rb +24 -0
  69. data/lib/cuprum/rails/responses/html/redirect_back_response.rb +55 -0
  70. data/lib/cuprum/rails/responses/html/redirect_response.rb +19 -4
  71. data/lib/cuprum/rails/responses/html/render_response.rb +17 -5
  72. data/lib/cuprum/rails/responses/html.rb +6 -2
  73. data/lib/cuprum/rails/responses.rb +1 -0
  74. data/lib/cuprum/rails/result.rb +36 -0
  75. data/lib/cuprum/rails/routes.rb +36 -23
  76. data/lib/cuprum/rails/rspec/contract_helpers.rb +57 -0
  77. data/lib/cuprum/rails/rspec/contracts/action_contracts.rb +754 -0
  78. data/lib/cuprum/rails/rspec/contracts/actions/create_contracts.rb +289 -0
  79. data/lib/cuprum/rails/rspec/contracts/actions/destroy_contracts.rb +164 -0
  80. data/lib/cuprum/rails/rspec/contracts/actions/edit_contracts.rb +73 -0
  81. data/lib/cuprum/rails/rspec/contracts/actions/index_contracts.rb +108 -0
  82. data/lib/cuprum/rails/rspec/contracts/actions/new_contracts.rb +111 -0
  83. data/lib/cuprum/rails/rspec/contracts/actions/show_contracts.rb +72 -0
  84. data/lib/cuprum/rails/rspec/contracts/actions/update_contracts.rb +263 -0
  85. data/lib/cuprum/rails/rspec/contracts/actions.rb +8 -0
  86. data/lib/cuprum/rails/rspec/contracts/command_contracts.rb +479 -0
  87. data/lib/cuprum/rails/rspec/contracts/responder_contracts.rb +232 -0
  88. data/lib/cuprum/rails/rspec/contracts/routes_contracts.rb +363 -0
  89. data/lib/cuprum/rails/rspec/contracts/serializers_contracts.rb +70 -0
  90. data/lib/cuprum/rails/rspec/contracts.rb +8 -0
  91. data/lib/cuprum/rails/rspec/matchers/be_a_result_matcher.rb +64 -0
  92. data/lib/cuprum/rails/rspec/matchers.rb +41 -0
  93. data/lib/cuprum/rails/serializers/base_serializer.rb +60 -0
  94. data/lib/cuprum/rails/serializers/context.rb +84 -0
  95. data/lib/cuprum/rails/serializers/json/active_record_serializer.rb +2 -2
  96. data/lib/cuprum/rails/serializers/json/array_serializer.rb +9 -8
  97. data/lib/cuprum/rails/serializers/json/attributes_serializer.rb +95 -172
  98. data/lib/cuprum/rails/serializers/json/error_serializer.rb +2 -2
  99. data/lib/cuprum/rails/serializers/json/hash_serializer.rb +9 -8
  100. data/lib/cuprum/rails/serializers/json/identity_serializer.rb +3 -3
  101. data/lib/cuprum/rails/serializers/json/properties_serializer.rb +252 -0
  102. data/lib/cuprum/rails/serializers/json.rb +2 -1
  103. data/lib/cuprum/rails/serializers.rb +3 -1
  104. data/lib/cuprum/rails/version.rb +1 -1
  105. data/lib/cuprum/rails.rb +19 -16
  106. metadata +73 -131
  107. data/lib/cuprum/rails/controller_action.rb +0 -121
  108. data/lib/cuprum/rails/errors/missing_parameters.rb +0 -33
  109. data/lib/cuprum/rails/errors/missing_primary_key.rb +0 -46
  110. data/lib/cuprum/rails/errors/undefined_permitted_attributes.rb +0 -34
  111. data/lib/cuprum/rails/rspec/command_contract.rb +0 -460
  112. data/lib/cuprum/rails/rspec/define_route_contract.rb +0 -84
  113. 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/html_responder'
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::HtmlResponder
21
- action :create do
22
- match :failure, error: Cuprum::Collections::Errors::FailedValidation do
23
- render :new,
24
- assigns: result.value.merge(errors: result.error.errors),
25
- status: 422 # rubocop:disable Rails/HttpStatus
26
- end
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.singular_resource_name]
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 resource.routes.index_path if result.value.nil?
76
+ return routes.index_path if result.value.nil?
121
77
 
122
78
  entity = resource_entity
123
79
 
124
- return resource.routes.show_path(entity) if entity
80
+ return routes.show_path(entity) if entity
125
81
 
126
- resource.routes.index_path
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/missing_parameters'
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 MissingParameters: serializes the error with status 400 Bad
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::MissingParameters do |result|
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(GENERIC_ERROR)
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] The name of the action to match.
54
- # @param matcher [Cuprum::Matcher] An optional matcher specific to the
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] True if the action acts on a collection
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 resource [Cuprum::Rails::Resource] The resource for the controller.
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
- resource:,
69
+ controller:,
70
+ request:,
62
71
  serializers:,
63
- matcher: nil,
64
72
  member_action: false,
65
- **_options
73
+ **options
66
74
  )
67
75
  super(
68
- action_name: action_name,
69
- matcher: matcher,
70
- member_action: member_action,
71
- resource: resource,
72
- root_serializer: Cuprum::Rails::Serializers::Json::Serializer.instance,
73
- serializers: serializers
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
- # @private
50
- def self.included(other)
51
- super
49
+ class << self
50
+ private
51
+
52
+ def included(other)
53
+ super
52
54
 
53
- other.extend(ClassMethods)
55
+ other.extend(ClassMethods)
56
+ end
54
57
  end
55
58
 
56
- # @param action_name [String, Symbol] The name of the action to match.
57
- # @param matcher [Cuprum::Matcher] An optional matcher specific to the
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] True if the action acts on a collection
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 resource [Cuprum::Rails::Resource] The resource for the controller.
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
- resource:,
65
- matcher: nil,
68
+ controller:,
69
+ request:,
70
+ matcher: nil,
66
71
  member_action: false,
67
- **_options
72
+ **options
68
73
  )
69
- @action_name = action_name
70
- @matcher = matcher
71
- @member_action = !!member_action # rubocop:disable Style/DoubleNegation
72
- @resource = resource
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
- # @return [#call, #renderer] The response object from the matching response
100
- # clause.
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(root_serializer:, serializers:, **options)
13
+ def initialize(serializers:, **options)
14
14
  super(**options)
15
15
 
16
- @root_serializer = root_serializer
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
- root_serializer.call(object, serializers: serializers)
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