mime_actor 0.6.2 → 0.6.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 +72 -71
- data/README.md +39 -43
- data/lib/mime_actor/action.rb +8 -9
- data/lib/mime_actor/callbacks.rb +201 -0
- data/lib/mime_actor/dispatcher.rb +11 -12
- data/lib/mime_actor/rescue.rb +5 -19
- data/lib/mime_actor/scene.rb +7 -15
- data/lib/mime_actor/stage.rb +17 -30
- data/lib/mime_actor/validator.rb +15 -1
- data/lib/mime_actor/version.rb +1 -1
- metadata +5 -10
- data/.hound.yml +0 -2
- data/.rspec +0 -1
- data/.rubocop.yml +0 -66
- data/.ruby-version +0 -1
- data/.yardopts +0 -2
- data/Rakefile +0 -9
- data/codecov.yml +0 -18
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c54b7a74eed15ac67b37d8df3879584634955ff4db0275cecc1dd4b7d531ec55
|
4
|
+
data.tar.gz: da797d40d7f90f5c6f8e23b61f2fe1441aef08860c6af5ff1763f49cee15ccaa
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 79eea272d7e8c3b625584eb8ae54790076035b511210302bb948076f54d847f34bb5c1f354d03b5fa319fbcc7c370f4c72a97b806593a732dd6207dfb8b6bbbe
|
7
|
+
data.tar.gz: 387780b44aafbcd60e79b7f9ebedd3c00edc40faa1acdce0c6946aad5787f053ae17ae62cab3ba84f8dd695874074e66ef867f6cfbb79e9ba947ddff837c7baa
|
data/COMPARE.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
## Comparison in Rails
|
2
2
|
|
3
|
-
### MIME
|
3
|
+
### MIME Action
|
4
4
|
|
5
5
|
#### before
|
6
6
|
```rb
|
@@ -22,103 +22,104 @@ end
|
|
22
22
|
#### after
|
23
23
|
```rb
|
24
24
|
class EventsController < ActionController::Base
|
25
|
-
|
25
|
+
include MimeActor::Action
|
26
26
|
|
27
|
-
|
27
|
+
before_act -> { @events = Event.all }, action: :index
|
28
28
|
|
29
|
-
|
30
|
-
|
29
|
+
# dynamically defines the action method according to on: argument
|
30
|
+
respond_act_to :html, :json, on: :index
|
31
31
|
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
32
|
+
def index_html
|
33
|
+
@event_categories = EventCategory.all
|
34
|
+
|
35
|
+
# render html using @events and @event_categories
|
36
|
+
render :index
|
37
|
+
end
|
38
38
|
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
39
|
+
def index_json
|
40
|
+
# render json using #as_json
|
41
|
+
render json: @events
|
42
|
+
end
|
43
43
|
end
|
44
44
|
```
|
45
45
|
|
46
|
-
### MIME
|
46
|
+
### MIME Rescue
|
47
47
|
|
48
48
|
#### before
|
49
49
|
```rb
|
50
50
|
class EventsController < ActionController::Base
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
raise ex # re-raise since we are not handling it
|
68
|
-
end
|
51
|
+
before_action only: %i[show update], with: :load_event
|
52
|
+
|
53
|
+
rescue_from ActiveRecord::RecordNotFound do |ex|
|
54
|
+
case action_name.to_s
|
55
|
+
when "show"
|
56
|
+
respond_to do |format|
|
57
|
+
format.html { redirect_to events_path } # redirect to index
|
58
|
+
format.json { render status: :bad_request, json: { error: ex.message } }
|
59
|
+
end
|
60
|
+
when "update"
|
61
|
+
respond_to do |format|
|
62
|
+
format.html { render :edit }
|
63
|
+
format.json { render status: :bad_request, json: { error: ex.message } }
|
64
|
+
end
|
65
|
+
else
|
66
|
+
raise ex # re-raise since we are not handling it
|
69
67
|
end
|
68
|
+
end
|
70
69
|
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
end
|
70
|
+
def show
|
71
|
+
respond_to do |format|
|
72
|
+
format.html { render :show } # render html using @event
|
73
|
+
format.json { render json: @event } # render json using #as_json
|
76
74
|
end
|
75
|
+
end
|
77
76
|
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
end
|
77
|
+
def update
|
78
|
+
# ...
|
79
|
+
respond_to do |format|
|
80
|
+
format.html { redirect_to event_path(@event.id) } # redirect to show upon sucessful update
|
81
|
+
format.json { render json: @event } # render json using #as_json
|
84
82
|
end
|
83
|
+
end
|
84
|
+
|
85
|
+
private
|
86
|
+
|
87
|
+
def load_event
|
88
|
+
@event = Event.find(params.require(:event_id))
|
89
|
+
end
|
85
90
|
end
|
86
91
|
```
|
87
92
|
#### after
|
88
93
|
```rb
|
89
94
|
class EventsController < ActionController::Base
|
90
|
-
|
95
|
+
include MimeActor::Action
|
91
96
|
|
92
|
-
|
93
|
-
before_action only: [:show, :update] { @event = Event.find(params.require(:event_id)) }
|
97
|
+
before_action only: %i[show update], with: :load_event
|
94
98
|
|
95
|
-
|
99
|
+
respond_act_to :html, on: %i[show update]
|
100
|
+
respond_act_to :json, on: %i[show update], with: -> { render json: @event } # render json using #as_json
|
96
101
|
|
97
|
-
|
98
|
-
render status: :bad_request, json: { error: ex.message }
|
99
|
-
end
|
102
|
+
rescue_act_from ActiveRecord::RecordNotFound, format: :json, with: :handle_json_error
|
100
103
|
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
+
rescue_act_from ActiveRecord::RecordNotFound, format: :html, action: :show do
|
105
|
+
redirect_to events_path
|
106
|
+
end
|
104
107
|
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
+
private
|
109
|
+
|
110
|
+
def show_html
|
111
|
+
render :show # render html using @event
|
112
|
+
end
|
108
113
|
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
def show_json
|
116
|
-
render json: @event # render json using #as_json
|
117
|
-
end
|
114
|
+
def update_html
|
115
|
+
# ...
|
116
|
+
redirect_to event_path(@event.id) # redirect to show upon sucessful update
|
117
|
+
rescue ActiveRecord::RecordNotFound
|
118
|
+
render :edit
|
119
|
+
end
|
118
120
|
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
end
|
121
|
+
def handle_json_error(error)
|
122
|
+
render status: :bad_request, json: { error: error.message }
|
123
|
+
end
|
123
124
|
end
|
124
125
|
```
|
data/README.md
CHANGED
@@ -5,55 +5,51 @@
|
|
5
5
|
[![Coverage][coverage_badge]][coverage]
|
6
6
|
[![Maintainability][maintainability_badge]][maintainability]
|
7
7
|
|
8
|
-
Action
|
8
|
+
Action processing with Callback + Rescue handlers for different MIME types in Rails.
|
9
9
|
|
10
10
|
## Usage
|
11
11
|
|
12
12
|
MimeActor allows you to do something like below:
|
13
13
|
```rb
|
14
14
|
class EventsController < ActionController::Base
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
def update_json
|
54
|
-
# ...
|
55
|
-
render json: @event # render json using #as_json
|
56
|
-
end
|
15
|
+
include MimeActor::Action
|
16
|
+
|
17
|
+
before_act -> { @events = Event.all }, action: :index
|
18
|
+
before_act :load_event, action: %i[show update]
|
19
|
+
|
20
|
+
respond_act_to :html, :json, on: :update
|
21
|
+
respond_act_to :html, on: %i[index show], with: :render_html
|
22
|
+
respond_act_to :json, on: %i[index show], with: -> { render json: { action: action_name } }
|
23
|
+
|
24
|
+
rescue_act_from ActiveRecord::RecordNotFound, format: :json, with: :handle_json_error
|
25
|
+
rescue_act_from ActiveRecord::RecordNotFound, format: :html, action: :show, with: -> { redirect_to "/events" }
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
def update_html
|
30
|
+
# ...
|
31
|
+
redirect_to "/events/#{@event.id}" # redirect to show upon sucessful update
|
32
|
+
rescue ActiveRecord::RecordNotFound
|
33
|
+
render html: :edit
|
34
|
+
end
|
35
|
+
|
36
|
+
def update_json
|
37
|
+
# ...
|
38
|
+
render json: @event # render json using #as_json
|
39
|
+
end
|
40
|
+
|
41
|
+
def render_html
|
42
|
+
@event_categories = EventCategory.all if action_name == :index
|
43
|
+
render html: action_name
|
44
|
+
end
|
45
|
+
|
46
|
+
def load_event
|
47
|
+
@event = Event.find(params.require(:event_id))
|
48
|
+
end
|
49
|
+
|
50
|
+
def handle_json_error(error)
|
51
|
+
render status: :bad_request, json: { error: error.message }
|
52
|
+
end
|
57
53
|
end
|
58
54
|
```
|
59
55
|
|
data/lib/mime_actor/action.rb
CHANGED
@@ -2,9 +2,9 @@
|
|
2
2
|
|
3
3
|
# :markup: markdown
|
4
4
|
|
5
|
+
require "mime_actor/logging"
|
5
6
|
require "mime_actor/scene"
|
6
7
|
require "mime_actor/stage"
|
7
|
-
require "mime_actor/rescue"
|
8
8
|
|
9
9
|
require "active_support/concern"
|
10
10
|
require "active_support/core_ext/object/blank"
|
@@ -17,7 +17,7 @@ module MimeActor
|
|
17
17
|
#
|
18
18
|
# `Action` is the recommended `Module` to be included in the `ActionController`.
|
19
19
|
#
|
20
|
-
# Provides intuitive way of `action`
|
20
|
+
# Provides intuitive way of `action` processing for a specific MIME type with callback + rescue handlers.
|
21
21
|
#
|
22
22
|
module Action
|
23
23
|
extend ActiveSupport::Concern
|
@@ -27,15 +27,13 @@ module MimeActor
|
|
27
27
|
|
28
28
|
include Scene
|
29
29
|
include Stage
|
30
|
-
include Rescue
|
31
30
|
include Logging
|
32
31
|
|
33
32
|
# The core logic where rendering logics are collected as `Proc` and passed over to `ActionController::MimeResponds`
|
34
33
|
#
|
35
|
-
# @param action the `action` of the controller
|
36
|
-
#
|
37
34
|
# @example process `create` action
|
38
|
-
#
|
35
|
+
# # it uses AbstractController#action_name to process
|
36
|
+
# start_scene
|
39
37
|
#
|
40
38
|
# # it is equivalent to the following if `create` action is configured with `html` and `json` formats
|
41
39
|
# def create
|
@@ -45,17 +43,18 @@ module MimeActor
|
|
45
43
|
# end
|
46
44
|
# end
|
47
45
|
#
|
48
|
-
def start_scene
|
46
|
+
def start_scene
|
47
|
+
action = action_name.to_sym
|
49
48
|
formats = acting_scenes.fetch(action, {})
|
50
49
|
|
51
50
|
if formats.empty?
|
52
|
-
logger.warn { "format is empty for action: #{
|
51
|
+
logger.warn { "format is empty for action: #{action_name.inspect}" }
|
53
52
|
return
|
54
53
|
end
|
55
54
|
|
56
55
|
respond_to do |collector|
|
57
56
|
formats.each do |format, actor|
|
58
|
-
dispatch = -> { cue_actor(actor.presence || "#{action}_#{format}",
|
57
|
+
dispatch = -> { cue_actor(actor.presence || "#{action}_#{format}", format:) }
|
59
58
|
collector.public_send(format, &dispatch)
|
60
59
|
end
|
61
60
|
end
|
@@ -0,0 +1,201 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# :markup: markdown
|
4
|
+
|
5
|
+
require "mime_actor/validator"
|
6
|
+
|
7
|
+
require "active_support/callbacks"
|
8
|
+
require "active_support/concern"
|
9
|
+
require "active_support/core_ext/array/wrap"
|
10
|
+
require "active_support/core_ext/object/blank"
|
11
|
+
|
12
|
+
module MimeActor
|
13
|
+
# # MimeActor Callbacks
|
14
|
+
#
|
15
|
+
# MimeActor provides hooks during the life cycle of an act. Available callbacks are:
|
16
|
+
#
|
17
|
+
# - before_act
|
18
|
+
# - around_act
|
19
|
+
# - after_act
|
20
|
+
#
|
21
|
+
# NOTE: Calling the same callback multiple times will overwrite previous callback definitions.
|
22
|
+
#
|
23
|
+
module Callbacks
|
24
|
+
extend ActiveSupport::Concern
|
25
|
+
|
26
|
+
include ActiveSupport::Callbacks
|
27
|
+
include MimeActor::Validator
|
28
|
+
|
29
|
+
included do
|
30
|
+
define_callbacks :act, skip_after_callbacks_if_terminated: true
|
31
|
+
|
32
|
+
%i[before after around].each { |kind| define_act_callbacks(kind) }
|
33
|
+
end
|
34
|
+
|
35
|
+
module ClassMethods
|
36
|
+
class ActionMatcher
|
37
|
+
def initialize(actions)
|
38
|
+
@actions = Array.wrap(actions).to_set(&:to_s)
|
39
|
+
end
|
40
|
+
|
41
|
+
def match?(controller)
|
42
|
+
@actions.include?(controller.action_name)
|
43
|
+
end
|
44
|
+
|
45
|
+
alias after match?
|
46
|
+
alias before match?
|
47
|
+
alias around match?
|
48
|
+
end
|
49
|
+
|
50
|
+
def callback_chain_name(format = nil)
|
51
|
+
if format.present?
|
52
|
+
validate!(:format, format)
|
53
|
+
:"act_#{format}"
|
54
|
+
else
|
55
|
+
:act
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def callback_chain_defined?(name)
|
60
|
+
!!get_callbacks(name)
|
61
|
+
end
|
62
|
+
|
63
|
+
private
|
64
|
+
|
65
|
+
def define_callback_chain(name)
|
66
|
+
return if callback_chain_defined?(name)
|
67
|
+
|
68
|
+
define_callbacks name, skip_after_callbacks_if_terminated: true
|
69
|
+
end
|
70
|
+
|
71
|
+
def configure_callbacks(callbacks, actions, formats, block)
|
72
|
+
options = {}
|
73
|
+
options[:if] = ActionMatcher.new(actions) if actions.present?
|
74
|
+
callbacks.push(block) if block
|
75
|
+
|
76
|
+
formats = Array.wrap(formats)
|
77
|
+
formats << nil if formats.empty?
|
78
|
+
|
79
|
+
callbacks.each do |callback|
|
80
|
+
formats.each do |format|
|
81
|
+
chain = callback_chain_name(format)
|
82
|
+
define_callback_chain(chain)
|
83
|
+
yield chain, callback, options
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
def validate_callback_options!(action, format)
|
89
|
+
validate!(:action_or_actions, action) if action.present?
|
90
|
+
validate!(:format_or_formats, format) if format.present?
|
91
|
+
end
|
92
|
+
|
93
|
+
def define_act_callbacks(kind)
|
94
|
+
module_eval(
|
95
|
+
# def self.before_act(*callbacks, action: nil, format: nil, &block)
|
96
|
+
# validate_callback_options!(action, format)
|
97
|
+
# configure_callbacks(callbacks, action, format, block) do |chain, callback, options|
|
98
|
+
# set_callback(chain, :before, callback, options)
|
99
|
+
# end
|
100
|
+
# end
|
101
|
+
#
|
102
|
+
# def self.prepend_before_act(*callbacks, action: nil, format: nil, &block)
|
103
|
+
# validate_callback_options!(action, format)
|
104
|
+
# configure_callbacks(callbacks, action, format, block) do |chain, callback, options|
|
105
|
+
# set_callback(chain, :before, callback, options.merge!(prepend: true))
|
106
|
+
# end
|
107
|
+
# end
|
108
|
+
<<-RUBY, __FILE__, __LINE__ + 1
|
109
|
+
def self.#{kind}_act(*callbacks, action: nil, format: nil, &block)
|
110
|
+
validate_callback_options!(action, format)
|
111
|
+
configure_callbacks(callbacks, action, format, block) do |chain, callback, options|
|
112
|
+
set_callback(chain, :#{kind}, callback, options)
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
def self.prepend_#{kind}_act(*callbacks, action: nil, format: nil, &block)
|
117
|
+
validate_callback_options!(action, format)
|
118
|
+
configure_callbacks(callbacks, action, format, block) do |chain, callback, options|
|
119
|
+
set_callback(chain, :#{kind}, callback, options.merge!(prepend: true))
|
120
|
+
end
|
121
|
+
end
|
122
|
+
RUBY
|
123
|
+
)
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
# Callbacks invocation sequence depends on the order of callback definition.
|
128
|
+
# (except for callbacks with `format` filter).
|
129
|
+
#
|
130
|
+
# @example callbacks with/without action filter
|
131
|
+
# before_act :my_before_act_one
|
132
|
+
# before_act :my_before_act_two, action: :create
|
133
|
+
# before_act :my_before_act_three
|
134
|
+
#
|
135
|
+
# around_act :my_around_act_one
|
136
|
+
# around_act :my_around_act_two, action: :create
|
137
|
+
# around_act :my_around_act_three
|
138
|
+
#
|
139
|
+
# after_act :my_after_act_one
|
140
|
+
# after_act :my_after_act_two, action: :create
|
141
|
+
# after_act :my_after_act_three
|
142
|
+
#
|
143
|
+
# # actual sequence:
|
144
|
+
# # - my_before_act_one
|
145
|
+
# # - my_before_act_two
|
146
|
+
# # - my_before_act_three
|
147
|
+
# # - my_around_act_one
|
148
|
+
# # - my_around_act_two
|
149
|
+
# # - my_around_act_three
|
150
|
+
# # - my_after_act_three
|
151
|
+
# # - my_after_act_two
|
152
|
+
# # - my_after_act_one
|
153
|
+
#
|
154
|
+
# @example callbacks with format filter
|
155
|
+
# before_act :my_before_act_one
|
156
|
+
# before_act :my_before_act_two, action: :create
|
157
|
+
# before_act :my_before_act_three, action: :create, format: :html
|
158
|
+
# before_act :my_before_act_four
|
159
|
+
#
|
160
|
+
# around_act :my_around_act_one
|
161
|
+
# around_act :my_around_act_two, action: :create, format: :html
|
162
|
+
# around_act :my_around_act_three, action: :create
|
163
|
+
# around_act :my_around_act_four
|
164
|
+
#
|
165
|
+
# after_act :my_after_act_one, format: :html
|
166
|
+
# after_act :my_after_act_two
|
167
|
+
# after_act :my_after_act_three, action: :create
|
168
|
+
# after_act :my_after_act_four
|
169
|
+
#
|
170
|
+
# # actual sequence:
|
171
|
+
# # - my_before_act_one
|
172
|
+
# # - my_before_act_two
|
173
|
+
# # - my_before_act_four
|
174
|
+
# # - my_around_act_one
|
175
|
+
# # - my_around_act_three
|
176
|
+
# # - my_around_act_four
|
177
|
+
# # - my_before_act_three
|
178
|
+
# # - my_around_act_two
|
179
|
+
# # - my_after_act_one
|
180
|
+
# # - my_after_act_four
|
181
|
+
# # - my_after_act_three
|
182
|
+
# # - my_after_act_two
|
183
|
+
#
|
184
|
+
def run_act_callbacks(format)
|
185
|
+
action_chain = self.class.callback_chain_name
|
186
|
+
format_chain = self.class.callback_chain_name(format)
|
187
|
+
|
188
|
+
if self.class.callback_chain_defined?(format_chain)
|
189
|
+
run_callbacks action_chain do
|
190
|
+
run_callbacks format_chain do
|
191
|
+
yield if block_given?
|
192
|
+
end
|
193
|
+
end
|
194
|
+
else
|
195
|
+
run_callbacks action_chain do
|
196
|
+
yield if block_given?
|
197
|
+
end
|
198
|
+
end
|
199
|
+
end
|
200
|
+
end
|
201
|
+
end
|
@@ -2,6 +2,8 @@
|
|
2
2
|
|
3
3
|
# :markup: markdown
|
4
4
|
|
5
|
+
require "mime_actor/errors"
|
6
|
+
|
5
7
|
module MimeActor
|
6
8
|
module Dispatcher
|
7
9
|
class MethodCall
|
@@ -13,13 +15,12 @@ module MimeActor
|
|
13
15
|
validate!
|
14
16
|
end
|
15
17
|
|
16
|
-
def
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
end
|
18
|
+
def call(target)
|
19
|
+
raise MimeActor::ActorNotFound, method_name unless target.respond_to?(method_name, true)
|
20
|
+
|
21
|
+
method_call = target.method(method_name)
|
22
|
+
filtered_args = method_call.arity.negative? ? args : args.take(method_call.arity)
|
23
|
+
method_call.call(*filtered_args)
|
23
24
|
end
|
24
25
|
|
25
26
|
private
|
@@ -38,11 +39,9 @@ module MimeActor
|
|
38
39
|
validate!
|
39
40
|
end
|
40
41
|
|
41
|
-
def
|
42
|
-
|
43
|
-
|
44
|
-
target.instance_exec(*filtered_args, &block)
|
45
|
-
end
|
42
|
+
def call(target)
|
43
|
+
filtered_args = block.arity.negative? ? args : args.take(block.arity)
|
44
|
+
target.instance_exec(*filtered_args, &block)
|
46
45
|
end
|
47
46
|
|
48
47
|
private
|
data/lib/mime_actor/rescue.rb
CHANGED
@@ -4,7 +4,6 @@
|
|
4
4
|
|
5
5
|
require "mime_actor/dispatcher"
|
6
6
|
require "mime_actor/validator"
|
7
|
-
require "mime_actor/stage"
|
8
7
|
|
9
8
|
require "active_support/concern"
|
10
9
|
require "active_support/core_ext/array/wrap"
|
@@ -23,7 +22,6 @@ module MimeActor
|
|
23
22
|
module Rescue
|
24
23
|
extend ActiveSupport::Concern
|
25
24
|
|
26
|
-
include Stage
|
27
25
|
include Validator
|
28
26
|
|
29
27
|
included do
|
@@ -51,19 +49,11 @@ module MimeActor
|
|
51
49
|
raise ArgumentError, "error filter is required" if klazzes.empty?
|
52
50
|
raise ArgumentError, "provide either the with: argument or a block" unless with.present? ^ block_given?
|
53
51
|
|
54
|
-
if
|
55
|
-
|
56
|
-
else
|
57
|
-
validate!(:with, with)
|
58
|
-
end
|
59
|
-
|
60
|
-
if action.present?
|
61
|
-
action.is_a?(Enumerable) ? validate!(:actions, action) : validate!(:action, action)
|
62
|
-
end
|
52
|
+
validate!(:with, with) if with.present?
|
53
|
+
with = block if block_given?
|
63
54
|
|
64
|
-
if
|
65
|
-
|
66
|
-
end
|
55
|
+
validate!(:action_or_actions, action) if action.present?
|
56
|
+
validate!(:format_or_formats, format) if format.present?
|
67
57
|
|
68
58
|
klazzes.each do |klazz|
|
69
59
|
validate!(:klazz, klazz)
|
@@ -156,11 +146,7 @@ module MimeActor
|
|
156
146
|
visited << error
|
157
147
|
rescuer = find_rescuer(error, format:, action:)
|
158
148
|
if (dispatch = MimeActor::Dispatcher.build(rescuer, error, format, action))
|
159
|
-
|
160
|
-
result = catch(:abort) do
|
161
|
-
dispatch.to_callable.call(self).tap { dispatched = true }
|
162
|
-
end
|
163
|
-
logger.error { "rescue error, cause: #{result.inspect}" } unless dispatched
|
149
|
+
dispatch.call(self)
|
164
150
|
error
|
165
151
|
elsif error&.cause
|
166
152
|
rescue_actor(error.cause, format:, action:, visited:)
|
data/lib/mime_actor/scene.rb
CHANGED
@@ -86,20 +86,12 @@ module MimeActor
|
|
86
86
|
|
87
87
|
raise ArgumentError, "provide either the with: argument or a block" if with.present? && block_given?
|
88
88
|
|
89
|
-
if
|
90
|
-
|
91
|
-
elsif with.present?
|
92
|
-
validate!(:with, with)
|
93
|
-
end
|
89
|
+
validate!(:with, with) if with.present?
|
90
|
+
with = block if block_given?
|
94
91
|
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
when Symbol, String
|
99
|
-
validate!(:action, actions)
|
100
|
-
else
|
101
|
-
raise ArgumentError, "action is required"
|
102
|
-
end
|
92
|
+
raise ArgumentError, "action is required" unless (actions = on).present?
|
93
|
+
|
94
|
+
validate!(:action_or_actions, actions)
|
103
95
|
|
104
96
|
Array.wrap(actions).each do |action|
|
105
97
|
formats.each { |format| compose_scene(action, format, with) }
|
@@ -124,11 +116,11 @@ module MimeActor
|
|
124
116
|
def define_scene(action)
|
125
117
|
module_eval(
|
126
118
|
# def index
|
127
|
-
# self.respond_to?(:start_scene) && self.start_scene
|
119
|
+
# self.respond_to?(:start_scene) && self.start_scene
|
128
120
|
# end
|
129
121
|
<<-RUBY, __FILE__, __LINE__ + 1
|
130
122
|
def #{action}
|
131
|
-
self.respond_to?(:start_scene) && self.start_scene
|
123
|
+
self.respond_to?(:start_scene) && self.start_scene
|
132
124
|
end
|
133
125
|
RUBY
|
134
126
|
)
|
data/lib/mime_actor/stage.rb
CHANGED
@@ -2,9 +2,10 @@
|
|
2
2
|
|
3
3
|
# :markup: markdown
|
4
4
|
|
5
|
-
require "mime_actor/
|
5
|
+
require "mime_actor/callbacks"
|
6
6
|
require "mime_actor/dispatcher"
|
7
7
|
require "mime_actor/logging"
|
8
|
+
require "mime_actor/rescue"
|
8
9
|
|
9
10
|
require "active_support/concern"
|
10
11
|
require "active_support/core_ext/module/attribute_accessors"
|
@@ -17,6 +18,8 @@ module MimeActor
|
|
17
18
|
module Stage
|
18
19
|
extend ActiveSupport::Concern
|
19
20
|
|
21
|
+
include Callbacks
|
22
|
+
include Rescue
|
20
23
|
include Logging
|
21
24
|
|
22
25
|
included do
|
@@ -75,38 +78,22 @@ module MimeActor
|
|
75
78
|
# @param actor either a method name or a Proc to evaluate
|
76
79
|
# @param args arguments to be passed when calling the actor
|
77
80
|
#
|
78
|
-
def cue_actor(actor, *args,
|
79
|
-
|
80
|
-
raise TypeError, "invalid actor, got: #{actor.inspect}" unless
|
81
|
+
def cue_actor(actor, *args, format:)
|
82
|
+
dispatcher = MimeActor::Dispatcher.build(actor, *args)
|
83
|
+
raise TypeError, "invalid actor, got: #{actor.inspect}" unless dispatcher
|
81
84
|
|
82
|
-
|
83
|
-
if block_given?
|
84
|
-
yield result
|
85
|
-
else
|
86
|
-
result
|
87
|
-
end
|
88
|
-
end
|
89
|
-
|
90
|
-
private
|
85
|
+
self.class.validate!(:format, format)
|
91
86
|
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
result = catch(:abort) do
|
96
|
-
dispatch.to_callable.call(self).tap { dispatched = true }
|
97
|
-
rescue StandardError => e
|
98
|
-
rescued = respond_to?(:rescue_actor) && rescue_actor(e, action:, format:)
|
99
|
-
raise unless rescued
|
87
|
+
run_act_callbacks(format) do
|
88
|
+
result = dispatcher.call(self)
|
89
|
+
block_given? ? yield(result) : result
|
100
90
|
end
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
raise error if raise_on_actor_error
|
108
|
-
|
109
|
-
logger.error { "actor error, cause: #{error.inspect}" }
|
91
|
+
rescue MimeActor::ActorNotFound => e
|
92
|
+
logger.error { "actor error, cause: #{e.inspect}" } unless raise_on_actor_error
|
93
|
+
raise e if raise_on_actor_error
|
94
|
+
rescue StandardError => e
|
95
|
+
rescued = rescue_actor(e, action: action_name.to_sym, format: format)
|
96
|
+
rescued || raise
|
110
97
|
end
|
111
98
|
end
|
112
99
|
end
|
data/lib/mime_actor/validator.rb
CHANGED
@@ -32,7 +32,7 @@ module MimeActor
|
|
32
32
|
# @param rule the name of validator
|
33
33
|
def validate!(rule, *args)
|
34
34
|
validator = "validate_#{rule}"
|
35
|
-
raise NameError, "Validator not found, got: #{validator.inspect}" unless respond_to?(validator
|
35
|
+
raise NameError, "Validator not found, got: #{validator.inspect}" unless respond_to?(validator)
|
36
36
|
|
37
37
|
error = send(validator, *args)
|
38
38
|
raise error if error
|
@@ -53,6 +53,13 @@ module MimeActor
|
|
53
53
|
NameError.new("invalid actions, got: #{rejected.map(&:inspect).join(", ")}") if rejected.size.positive?
|
54
54
|
end
|
55
55
|
|
56
|
+
# Validate against `actions` rule if argument is a Enumerable. otherwise, validate against `action` rule.
|
57
|
+
#
|
58
|
+
# @param unchecked the `actions` or `action` to be validated
|
59
|
+
def validate_action_or_actions(unchecked)
|
60
|
+
unchecked.is_a?(Enumerable) ? validate_actions(unchecked) : validate_action(unchecked)
|
61
|
+
end
|
62
|
+
|
56
63
|
# Validate `format` must be a Symbol and a valid MIME type
|
57
64
|
#
|
58
65
|
# @param unchecked the `format` to be validated
|
@@ -73,6 +80,13 @@ module MimeActor
|
|
73
80
|
NameError.new("invalid formats, got: #{rejected.map(&:inspect).join(", ")}") if rejected.size.positive?
|
74
81
|
end
|
75
82
|
|
83
|
+
# Validate against `formats` rule if argument is a Enumerable. otherwise, validate against `format` rule.
|
84
|
+
#
|
85
|
+
# @param unchecked the `formats` or `format` to be validated
|
86
|
+
def validate_format_or_formats(unchecked)
|
87
|
+
unchecked.is_a?(Enumerable) ? validate_formats(unchecked) : validate_format(unchecked)
|
88
|
+
end
|
89
|
+
|
76
90
|
# Validate `klazz` must be a Class/Module or a String referencing a Class/Module
|
77
91
|
#
|
78
92
|
# @param unchecked the `klazz` to be validated
|
data/lib/mime_actor/version.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.6.
|
4
|
+
version: 0.6.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-07-
|
11
|
+
date: 2024-07-25 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: actionpack
|
@@ -59,18 +59,12 @@ executables: []
|
|
59
59
|
extensions: []
|
60
60
|
extra_rdoc_files: []
|
61
61
|
files:
|
62
|
-
- ".hound.yml"
|
63
|
-
- ".rspec"
|
64
|
-
- ".rubocop.yml"
|
65
|
-
- ".ruby-version"
|
66
|
-
- ".yardopts"
|
67
62
|
- COMPARE.md
|
68
63
|
- LICENSE
|
69
64
|
- README.md
|
70
|
-
- Rakefile
|
71
|
-
- codecov.yml
|
72
65
|
- lib/mime_actor.rb
|
73
66
|
- lib/mime_actor/action.rb
|
67
|
+
- lib/mime_actor/callbacks.rb
|
74
68
|
- lib/mime_actor/dispatcher.rb
|
75
69
|
- lib/mime_actor/errors.rb
|
76
70
|
- lib/mime_actor/logging.rb
|
@@ -107,5 +101,6 @@ requirements: []
|
|
107
101
|
rubygems_version: 3.5.9
|
108
102
|
signing_key:
|
109
103
|
specification_version: 4
|
110
|
-
summary: Action
|
104
|
+
summary: Action processing with Callback + Rescue handlers for different MIME types
|
105
|
+
in Rails
|
111
106
|
test_files: []
|
data/.hound.yml
DELETED
data/.rspec
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
--require spec_helper
|
data/.rubocop.yml
DELETED
@@ -1,66 +0,0 @@
|
|
1
|
-
require:
|
2
|
-
- rubocop-rake
|
3
|
-
- rubocop-rspec
|
4
|
-
|
5
|
-
AllCops:
|
6
|
-
TargetRubyVersion: 3.1
|
7
|
-
NewCops: enable
|
8
|
-
Exclude:
|
9
|
-
- bin/*
|
10
|
-
- vendor/**/*
|
11
|
-
|
12
|
-
Style/Documentation:
|
13
|
-
Enabled: false
|
14
|
-
|
15
|
-
Style/BlockComments:
|
16
|
-
Exclude:
|
17
|
-
- spec/*_helper.rb
|
18
|
-
|
19
|
-
Style/RegexpLiteral:
|
20
|
-
EnforcedStyle: percent_r
|
21
|
-
|
22
|
-
Metrics/AbcSize:
|
23
|
-
Enabled: false
|
24
|
-
|
25
|
-
Metrics/BlockLength:
|
26
|
-
AllowedMethods:
|
27
|
-
- class_methods
|
28
|
-
|
29
|
-
Metrics/CyclomaticComplexity:
|
30
|
-
Enabled: false
|
31
|
-
|
32
|
-
Metrics/PerceivedComplexity:
|
33
|
-
Enabled: false
|
34
|
-
|
35
|
-
Metrics/MethodLength:
|
36
|
-
CountAsOne: ['array', 'heredoc', 'method_call']
|
37
|
-
Max: 15
|
38
|
-
|
39
|
-
Style/StringLiterals:
|
40
|
-
EnforcedStyle: double_quotes
|
41
|
-
|
42
|
-
Style/StringLiteralsInInterpolation:
|
43
|
-
EnforcedStyle: double_quotes
|
44
|
-
|
45
|
-
Style/HashSyntax:
|
46
|
-
EnforcedShorthandSyntax: consistent
|
47
|
-
|
48
|
-
Layout/FirstHashElementIndentation:
|
49
|
-
EnforcedStyle: consistent
|
50
|
-
|
51
|
-
Layout/HashAlignment:
|
52
|
-
EnforcedHashRocketStyle: table
|
53
|
-
EnforcedColonStyle: table
|
54
|
-
|
55
|
-
RSpec/MultipleExpectations:
|
56
|
-
Max: 6
|
57
|
-
|
58
|
-
RSpec/ExampleLength:
|
59
|
-
CountAsOne: ['array', 'heredoc', 'method_call']
|
60
|
-
Max: 10
|
61
|
-
|
62
|
-
RSpec/MultipleMemoizedHelpers:
|
63
|
-
Max: 10
|
64
|
-
|
65
|
-
RSpec/NestedGroups:
|
66
|
-
Max: 5
|
data/.ruby-version
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
3.3.1
|
data/.yardopts
DELETED
data/Rakefile
DELETED
data/codecov.yml
DELETED