mime_actor 0.5.1 → 0.5.3
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/COMPARE.md +124 -0
- data/README.md +28 -7
- data/lib/mime_actor/action.rb +8 -0
- data/lib/mime_actor/logging.rb +5 -0
- data/lib/mime_actor/rescue.rb +18 -0
- data/lib/mime_actor/scene.rb +15 -0
- data/lib/mime_actor/stage.rb +16 -0
- data/lib/mime_actor/validator.rb +25 -0
- data/lib/mime_actor/version.rb +1 -1
- data/lib/mime_actor.rb +3 -0
- metadata +4 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 709cab49cc347653da124ec9147c7527b96f71df08059b6eab45a5d9b5b06888
|
4
|
+
data.tar.gz: ac9a75000c8711550971fa0d6e4f0ba3bc2b9e706ebd1654702df1b56d3e0f5d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 40fe1d6ba3560b836c12ec423d8285497f2576f231a385ecf910942cedd8be7c36ea1d20077283f2aa336c0aa1beab92a6472b998a63fde4a3b9de1e71f5a9c3
|
7
|
+
data.tar.gz: 5dc2dcc8697d65e386bf47f898b4ed85b8fe7d364ddfce84be873b966653c713e788c994a57e879e439ae1f6401e69092905dd88319a52c94f8c1be817daa1ca
|
data/COMPARE.md
ADDED
@@ -0,0 +1,124 @@
|
|
1
|
+
## Comparison in Rails
|
2
|
+
|
3
|
+
### MIME Rendering
|
4
|
+
|
5
|
+
#### before
|
6
|
+
```rb
|
7
|
+
class EventsController < ActionController::Base
|
8
|
+
def index
|
9
|
+
@events = Event.all
|
10
|
+
respond_to do |format|
|
11
|
+
format.html do
|
12
|
+
@event_categories = EventCategory.all
|
13
|
+
|
14
|
+
# render html using @events and @event_categories
|
15
|
+
render :index
|
16
|
+
end
|
17
|
+
format.json { render json: @events } # render json using #as_json
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
```
|
22
|
+
#### after
|
23
|
+
```rb
|
24
|
+
class EventsController < ActionController::Base
|
25
|
+
include MimeActor::Action
|
26
|
+
|
27
|
+
before_action only: :index { @events = Event.all }
|
28
|
+
|
29
|
+
# dynamically defines the action method according to on: argument
|
30
|
+
compose_scene :html, :json, on: :index
|
31
|
+
|
32
|
+
def index_html
|
33
|
+
@event_categories = EventCategory.all
|
34
|
+
|
35
|
+
# render html using @events and @event_categories
|
36
|
+
render :index
|
37
|
+
end
|
38
|
+
|
39
|
+
def index_json
|
40
|
+
# render json using #as_json
|
41
|
+
render json: @events
|
42
|
+
end
|
43
|
+
end
|
44
|
+
```
|
45
|
+
|
46
|
+
### MIME Rescuing
|
47
|
+
|
48
|
+
#### before
|
49
|
+
```rb
|
50
|
+
class EventsController < ActionController::Base
|
51
|
+
# AbstractController::Callbacks here to load model with params
|
52
|
+
before_action only: [:show, :update] { @event = Event.find(params.require(:event_id)) }
|
53
|
+
|
54
|
+
rescue_from ActiveRecord::RecordNotFound do |ex|
|
55
|
+
case action_name.to_s
|
56
|
+
when "show"
|
57
|
+
respond_to do |format|
|
58
|
+
format.html { redirect_to events_path } # redirect to index
|
59
|
+
format.json { render status: :bad_request, json: { error: ex.message } }
|
60
|
+
end
|
61
|
+
when "update"
|
62
|
+
respond_to do |format|
|
63
|
+
format.html { render :edit }
|
64
|
+
format.json { render status: :bad_request, json: { error: ex.message } }
|
65
|
+
end
|
66
|
+
else
|
67
|
+
raise ex # re-raise since we are not handling it
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
def show
|
72
|
+
respond_to do |format|
|
73
|
+
format.html { render :show } # render html using @event
|
74
|
+
format.json { render json: @event } # render json using #as_json
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
def update
|
79
|
+
# ...
|
80
|
+
respond_to do |format|
|
81
|
+
format.html { redirect_to event_path(@event.id) } # redirect to show upon sucessful update
|
82
|
+
format.json { render json: @event } # render json using #as_json
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
```
|
87
|
+
#### after
|
88
|
+
```rb
|
89
|
+
class EventsController < ActionController::Base
|
90
|
+
include MimeActor::Action
|
91
|
+
|
92
|
+
# AbstractController::Callbacks here to load model with params
|
93
|
+
before_action only: [:show, :update] { @event = Event.find(params.require(:event_id)) }
|
94
|
+
|
95
|
+
compose_scene :html, :json, on: [:show, :update]
|
96
|
+
|
97
|
+
rescue_actor_from ActiveRecord::RecordNotFound, format: :json do |ex|
|
98
|
+
render status: :bad_request, json: { error: ex.message }
|
99
|
+
end
|
100
|
+
|
101
|
+
rescue_actor_from ActiveRecord::RecordNotFound, format: :html, action: :show do |ex|
|
102
|
+
redirect_to events_path
|
103
|
+
end
|
104
|
+
|
105
|
+
def show_html
|
106
|
+
render :show # render html using @event
|
107
|
+
end
|
108
|
+
|
109
|
+
def update_html
|
110
|
+
redirect_to event_path(@event.id) # redirect to show upon sucessful update
|
111
|
+
rescue ActiveRecord::RecordNotFound
|
112
|
+
render :edit
|
113
|
+
end
|
114
|
+
|
115
|
+
def show_json
|
116
|
+
render json: @event # render json using #as_json
|
117
|
+
end
|
118
|
+
|
119
|
+
def update_json
|
120
|
+
# ...
|
121
|
+
render json: @event # render json using #as_json
|
122
|
+
end
|
123
|
+
end
|
124
|
+
```
|
data/README.md
CHANGED
@@ -1,10 +1,11 @@
|
|
1
1
|
# mime_actor
|
2
2
|
|
3
|
-
[![
|
4
|
-
[![
|
5
|
-
[![
|
3
|
+
[![Version][rubygems_badge]][rubygems]
|
4
|
+
[![CI][ci_badge]][ci_workflows]
|
5
|
+
[![Coverage][coverage_badge]][coverage]
|
6
|
+
[![Maintainability][maintainability_badge]][maintainability]
|
6
7
|
|
7
|
-
Render + Rescue handlers for different MIME types in Rails
|
8
|
+
Action Render + Rescue handlers for different MIME types in Rails
|
8
9
|
|
9
10
|
## Usage
|
10
11
|
|
@@ -56,13 +57,19 @@ class EventsController < ActionController::Base
|
|
56
57
|
end
|
57
58
|
```
|
58
59
|
|
60
|
+
Seems useful? See the [Comparison][doc_comparison] on how it can improve your existing code
|
61
|
+
|
59
62
|
## Features
|
60
63
|
|
61
|
-
- Action customisation for ActionController per MIME type
|
64
|
+
- Action customisation for [ActionController][doc_action_controller] per MIME type
|
62
65
|
- Customisation are deduplicated automatically when configured multiple times
|
63
66
|
- Flexible rescue handler definition for the combination of Action/MIME type or both
|
64
|
-
- Built on top of
|
65
|
-
- Fully compatible with other
|
67
|
+
- Built on top of [ActionController::Metal::MimeResponds][doc_action_controller_mime_responds]
|
68
|
+
- Fully compatible with other [ActionController][doc_action_controller] functionalities
|
69
|
+
|
70
|
+
## Documentation
|
71
|
+
|
72
|
+
You can find the documentation on [RubyDoc][doc_mime_actor].
|
66
73
|
|
67
74
|
## Requirements
|
68
75
|
|
@@ -93,3 +100,17 @@ Please see [LICENSE](https://github.com/ryancyq/mime_actor/blob/main/LICENSE) fo
|
|
93
100
|
## Contributing
|
94
101
|
|
95
102
|
Bug reports and pull requests are welcome on GitHub at https://github.com/ryancyq/mime_actor.
|
103
|
+
|
104
|
+
[rubygems_badge]: https://img.shields.io/gem/v/mime_actor.svg
|
105
|
+
[rubygems]: https://rubygems.org/gems/mime_actor
|
106
|
+
[ci_badge]: https://github.com/ryancyq/mime_actor/actions/workflows/build.yml/badge.svg
|
107
|
+
[ci_workflows]: https://github.com/ryancyq/mime_actor/actions/workflows/
|
108
|
+
[coverage_badge]: https://codecov.io/gh/ryancyq/mime_actor/graph/badge.svg?token=4C091RHXC3
|
109
|
+
[coverage]: https://codecov.io/gh/ryancyq/mime_actor
|
110
|
+
[maintainability_badge]: https://api.codeclimate.com/v1/badges/06689606dc3f3945dc1b/maintainability
|
111
|
+
[maintainability]: https://codeclimate.com/github/ryancyq/mime_actor/maintainability
|
112
|
+
|
113
|
+
[doc_mime_actor]: https://rubydoc.info/gems/mime_actor
|
114
|
+
[doc_action_controller]: https://rubydoc.info/gems/actionpack/ActionController/Metal
|
115
|
+
[doc_action_controller_mime_responds]: https://rubydoc.info/gems/actionpack/ActionController/MimeResponds
|
116
|
+
[doc_comparison]: https://github.com/ryancyq/mime_actor/blob/main/COMPARE.md
|
data/lib/mime_actor/action.rb
CHANGED
@@ -10,6 +10,12 @@ require "abstract_controller/rendering"
|
|
10
10
|
require "action_controller/metal/mime_responds"
|
11
11
|
|
12
12
|
module MimeActor
|
13
|
+
# # MimeActor Action
|
14
|
+
#
|
15
|
+
# Action is the recommended Module to be included in ActionController.
|
16
|
+
#
|
17
|
+
# Provides intuitive way of action rendering for a specific MIME type with rescue handlers.
|
18
|
+
#
|
13
19
|
module Action
|
14
20
|
extend ActiveSupport::Concern
|
15
21
|
|
@@ -21,6 +27,8 @@ module MimeActor
|
|
21
27
|
include Rescue
|
22
28
|
include Logging
|
23
29
|
|
30
|
+
##
|
31
|
+
# The core logic where rendering logics are collected as Proc through configuration and passed over to ActionController::MimeResponds
|
24
32
|
def start_scene(action)
|
25
33
|
action = action&.to_sym
|
26
34
|
formats = acting_scenes.fetch(action, Set.new)
|
data/lib/mime_actor/logging.rb
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
# :markup: markdown
|
4
|
+
|
3
5
|
require "active_support/concern"
|
4
6
|
require "active_support/configurable"
|
5
7
|
require "active_support/isolated_execution_state" # required by active_support/logger
|
@@ -7,6 +9,9 @@ require "active_support/logger"
|
|
7
9
|
require "active_support/tagged_logging"
|
8
10
|
|
9
11
|
module MimeActor
|
12
|
+
# # MimeActor Logging
|
13
|
+
#
|
14
|
+
# Provides a configurable logger.
|
10
15
|
module Logging
|
11
16
|
extend ActiveSupport::Concern
|
12
17
|
|
data/lib/mime_actor/rescue.rb
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
# :markup: markdown
|
4
|
+
|
3
5
|
require "mime_actor/stage"
|
4
6
|
require "mime_actor/validator"
|
5
7
|
|
@@ -9,6 +11,10 @@ require "active_support/core_ext/module/attribute_accessors"
|
|
9
11
|
require "active_support/core_ext/string/inflections"
|
10
12
|
|
11
13
|
module MimeActor
|
14
|
+
# # MimeActor Rescue
|
15
|
+
#
|
16
|
+
# Simillar to ActionController::Rescue but with additional filtering logic on Action/Format.
|
17
|
+
#
|
12
18
|
module Rescue
|
13
19
|
extend ActiveSupport::Concern
|
14
20
|
|
@@ -20,6 +26,15 @@ module MimeActor
|
|
20
26
|
end
|
21
27
|
|
22
28
|
module ClassMethods
|
29
|
+
##
|
30
|
+
# Registers a rescue handler for the given error classes with action/format filter
|
31
|
+
#
|
32
|
+
# rescue_actor_from StandardError, format: :json, action: :show do |ex|
|
33
|
+
# render status: :bad_request, json: { error: ex.message }
|
34
|
+
# end
|
35
|
+
#
|
36
|
+
# rescue_actor_from StandardError, format: :html, with: :handle_html_error
|
37
|
+
#
|
23
38
|
def rescue_actor_from(*klazzes, action: nil, format: nil, with: nil, &block)
|
24
39
|
raise ArgumentError, "error filter is required" if klazzes.empty?
|
25
40
|
|
@@ -58,6 +73,9 @@ module MimeActor
|
|
58
73
|
end
|
59
74
|
end
|
60
75
|
|
76
|
+
##
|
77
|
+
# Resolve the error provided with the registered handlers.
|
78
|
+
# The handled error will be returned to indicate successful handling
|
61
79
|
def rescue_actor(error, action: nil, format: nil, context: self, visited: [])
|
62
80
|
return if visited.include?(error)
|
63
81
|
|
data/lib/mime_actor/scene.rb
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
# :markup: markdown
|
4
|
+
|
3
5
|
require "mime_actor/errors"
|
4
6
|
require "mime_actor/validator"
|
5
7
|
|
@@ -9,6 +11,15 @@ require "active_support/core_ext/array/wrap"
|
|
9
11
|
require "active_support/core_ext/module/attribute_accessors"
|
10
12
|
|
11
13
|
module MimeActor
|
14
|
+
# # MimeActor Scene
|
15
|
+
#
|
16
|
+
# Scene provides configuration for Action + Format definitions
|
17
|
+
#
|
18
|
+
# compose_scene :html, on: :index
|
19
|
+
# compose_scene :html, :json , on: [:index, :show]
|
20
|
+
#
|
21
|
+
# NOTE: Calling the same action/format multiple times will overwrite previous Action + Format definitions.
|
22
|
+
#
|
12
23
|
module Scene
|
13
24
|
extend ActiveSupport::Concern
|
14
25
|
|
@@ -19,6 +30,10 @@ module MimeActor
|
|
19
30
|
end
|
20
31
|
|
21
32
|
module ClassMethods
|
33
|
+
##
|
34
|
+
# Register Action + Format definitions.
|
35
|
+
#
|
36
|
+
# For each unique action being registered, it will have a corresponding method being defined.
|
22
37
|
def compose_scene(*options)
|
23
38
|
config = options.extract_options!
|
24
39
|
validate!(:formats, options)
|
data/lib/mime_actor/stage.rb
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
# :markup: markdown
|
4
|
+
|
3
5
|
require "mime_actor/errors"
|
4
6
|
require "mime_actor/logging"
|
5
7
|
|
@@ -7,6 +9,10 @@ require "active_support/concern"
|
|
7
9
|
require "active_support/core_ext/module/attribute_accessors"
|
8
10
|
|
9
11
|
module MimeActor
|
12
|
+
# # MimeActor Stage
|
13
|
+
#
|
14
|
+
# Stage provides helpers for actor lookup and invocation.
|
15
|
+
#
|
10
16
|
module Stage
|
11
17
|
extend ActiveSupport::Concern
|
12
18
|
|
@@ -17,6 +23,8 @@ module MimeActor
|
|
17
23
|
end
|
18
24
|
|
19
25
|
module ClassMethods
|
26
|
+
##
|
27
|
+
# Determine if the name belongs to a public instance method excluding methods inherited from ancesstors
|
20
28
|
def actor?(actor_name)
|
21
29
|
# exclude public methods from ancestors
|
22
30
|
found = public_instance_methods(false).include?(actor_name.to_sym)
|
@@ -27,7 +35,11 @@ module MimeActor
|
|
27
35
|
found
|
28
36
|
end
|
29
37
|
|
38
|
+
##
|
39
|
+
# Wraps the given block with lambda, rescue any error raised from the block via #rescue_actor if defined, otherwise, error will be re-raised
|
30
40
|
def dispatch_cue(action: nil, format: nil, context: self, &block)
|
41
|
+
raise ArgumentError, "block must be provided" unless block_given?
|
42
|
+
|
31
43
|
lambda do
|
32
44
|
context.instance_exec(&block)
|
33
45
|
rescue StandardError => e
|
@@ -36,6 +48,10 @@ module MimeActor
|
|
36
48
|
end
|
37
49
|
end
|
38
50
|
|
51
|
+
##
|
52
|
+
# Call the actor method if defined, supports passing arguments to the actor method.
|
53
|
+
#
|
54
|
+
# If a block is given, the result from the actor method will be yieled to the block
|
39
55
|
def cue_actor(actor_name, *args)
|
40
56
|
unless self.class.actor?(actor_name)
|
41
57
|
raise MimeActor::ActorNotFound, actor_name if raise_on_missing_actor
|
data/lib/mime_actor/validator.rb
CHANGED
@@ -1,10 +1,23 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
# :markup: markdown
|
4
|
+
|
3
5
|
require "active_support/concern"
|
4
6
|
require "set" # required by mime_type with ruby <= 3.1
|
5
7
|
require "action_dispatch/http/mime_type"
|
6
8
|
|
7
9
|
module MimeActor
|
10
|
+
# # MimeActor Validator
|
11
|
+
#
|
12
|
+
# Validator provides validation rules for action, format, and rescue handlers by default.
|
13
|
+
#
|
14
|
+
# # raise error when rule is violated
|
15
|
+
# validate!(:action, action_param)
|
16
|
+
#
|
17
|
+
# # return the error when rule is violated
|
18
|
+
# ex = validate_action(action_param)
|
19
|
+
# raise ex if error
|
20
|
+
#
|
8
21
|
module Validator
|
9
22
|
extend ActiveSupport::Concern
|
10
23
|
|
@@ -13,6 +26,8 @@ module MimeActor
|
|
13
26
|
end
|
14
27
|
|
15
28
|
module ClassMethods
|
29
|
+
##
|
30
|
+
# Raise the error returned by validator if present.
|
16
31
|
def validate!(rule, *args)
|
17
32
|
validator = "validate_#{rule}"
|
18
33
|
raise NameError, "Validator not found, got: #{validator}" unless respond_to?(validator, true)
|
@@ -21,21 +36,29 @@ module MimeActor
|
|
21
36
|
raise error if error
|
22
37
|
end
|
23
38
|
|
39
|
+
##
|
40
|
+
# validate :action must be a Symbol
|
24
41
|
def validate_action(unchecked)
|
25
42
|
ArgumentError.new("action must be a Symbol") unless unchecked.is_a?(Symbol)
|
26
43
|
end
|
27
44
|
|
45
|
+
##
|
46
|
+
# validate :actions must be an Array of Symbol
|
28
47
|
def validate_actions(unchecked)
|
29
48
|
rejected = unchecked.reject { |action| action.is_a?(Symbol) }
|
30
49
|
NameError.new("invalid actions, got: #{rejected.join(", ")}") if rejected.size.positive?
|
31
50
|
end
|
32
51
|
|
52
|
+
##
|
53
|
+
# validate :format must be a Symbol + a valid MIME type
|
33
54
|
def validate_format(unchecked)
|
34
55
|
return ArgumentError.new("format must be a Symbol") unless unchecked.is_a?(Symbol)
|
35
56
|
|
36
57
|
NameError.new("invalid format, got: #{unchecked}") unless scene_formats.include?(unchecked)
|
37
58
|
end
|
38
59
|
|
60
|
+
##
|
61
|
+
# validate :formats must be an Array of Symbol which each of them is a valid MIME type
|
39
62
|
def validate_formats(unchecked)
|
40
63
|
unfiltered = unchecked.to_set
|
41
64
|
filtered = unfiltered & scene_formats
|
@@ -44,6 +67,8 @@ module MimeActor
|
|
44
67
|
NameError.new("invalid formats, got: #{rejected.join(", ")}") if rejected.size.positive?
|
45
68
|
end
|
46
69
|
|
70
|
+
##
|
71
|
+
# validate :with or &block must be provided + :with must be a Symbol or Proc
|
47
72
|
def validate_with(unchecked, block)
|
48
73
|
if unchecked.present? && block.present?
|
49
74
|
return ArgumentError.new("provide either the with: keyword argument or a block")
|
data/lib/mime_actor/version.rb
CHANGED
data/lib/mime_actor.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mime_actor
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.5.
|
4
|
+
version: 0.5.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ryan Chang
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-06-
|
11
|
+
date: 2024-06-29 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: actionpack
|
@@ -63,6 +63,7 @@ files:
|
|
63
63
|
- ".rspec"
|
64
64
|
- ".rubocop.yml"
|
65
65
|
- ".ruby-version"
|
66
|
+
- COMPARE.md
|
66
67
|
- LICENSE
|
67
68
|
- README.md
|
68
69
|
- Rakefile
|
@@ -103,5 +104,5 @@ requirements: []
|
|
103
104
|
rubygems_version: 3.5.9
|
104
105
|
signing_key:
|
105
106
|
specification_version: 4
|
106
|
-
summary:
|
107
|
+
summary: Action Render + Rescue handlers for different MIME types in Rails
|
107
108
|
test_files: []
|