action_handler 0.0.0 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +7 -11
- data/lib/action_handler/args_maker.rb +36 -6
- data/lib/action_handler/config.rb +0 -8
- data/lib/action_handler/controller.rb +2 -3
- data/lib/action_handler/equip.rb +0 -4
- data/lib/action_handler/installer.rb +28 -9
- data/lib/action_handler/version.rb +1 -1
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 06a9029c41b4a4ad4284e7e91f59724885da4f47b75b561cb30ed03f76734e19
|
4
|
+
data.tar.gz: ffbd72526d8bf9977a6807da8c10596db7b788d0596f50c558f216cc5af38f06
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: be995c1aea5765076ec538b25558a67c7105aa212aa9432e3bf1a83cd0b76dd6a94019dd121dcc6b00e130f6e554aa7c0997aab98bd10c52df9635fead2ce409
|
7
|
+
data.tar.gz: fccdd48b45bf653d32a27165945c45c6c174ec8ee872a356b22271ce4946a01f86dc1edcc39257b31426e8c23ce66b69e46d4900fd28e8abd775b59f60633a05
|
data/README.md
CHANGED
@@ -8,9 +8,9 @@ ActionHandler is a Rails plugin that helps you write controller functionalities
|
|
8
8
|
|
9
9
|
A handler is a controller-like class. Each public method can be an action method.
|
10
10
|
But unlike controllers, handlers inherit few methods by default.
|
11
|
-
|
11
|
+
Instead of using super class methods such as `params`, `sessions`, you can take them as arguments.
|
12
12
|
And you need to represent a response (data for views) as a single return value,
|
13
|
-
instead of
|
13
|
+
instead of assigning multiple instance variables.
|
14
14
|
|
15
15
|
```ruby
|
16
16
|
# Example
|
@@ -56,8 +56,7 @@ end
|
|
56
56
|
|
57
57
|
### Clean and clear structure
|
58
58
|
|
59
|
-
- In handlers, action methods take necessary inputs as arguments and
|
60
|
-
return output as a return value.
|
59
|
+
- In handlers, action methods take necessary inputs as arguments and represent output as a return value.
|
61
60
|
So easy to read and test.
|
62
61
|
- Handler is just a class, so you can set up any dependencies via `initialize` method.
|
63
62
|
|
@@ -67,7 +66,7 @@ end
|
|
67
66
|
just by declaring them as action method's arguments.
|
68
67
|
- You can define custom injectable arguments as well.
|
69
68
|
|
70
|
-
|
69
|
+
This feature is heavily inspired by [ActionArgs](https://github.com/asakusarb/action_args).
|
71
70
|
|
72
71
|
## Motivation
|
73
72
|
|
@@ -121,11 +120,8 @@ to use basic controller functionalities like `redirect_to` or custom arguments.
|
|
121
120
|
|
122
121
|
## Guides
|
123
122
|
|
124
|
-
|
123
|
+
- [Detail guides][wiki]
|
124
|
+
- [Example Rails app][example]
|
125
125
|
|
126
126
|
[wiki]: https://github.com/ryym/action_handler/wiki
|
127
|
-
|
128
|
-
TODO:
|
129
|
-
|
130
|
-
- Currently Unsupported controller features
|
131
|
-
- Where should handlers be placed?
|
127
|
+
[example]: https://github.com/ryym/action_handler/tree/master/examples/sample
|
@@ -1,18 +1,48 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module ActionHandler
|
4
|
-
class
|
5
|
-
|
4
|
+
class ActionArgumentError < StandardError
|
5
|
+
def initialize(method, details)
|
6
|
+
super("Arguments of #{method.owner.name}##{method.name} is invalid: #{details}")
|
7
|
+
end
|
8
|
+
end
|
6
9
|
|
7
|
-
|
10
|
+
class ArgsMaker
|
11
|
+
def make_args(method, supplier, context: nil)
|
8
12
|
supplier_args = [context].compact
|
9
|
-
|
13
|
+
|
14
|
+
values = []
|
15
|
+
keywords = {}
|
16
|
+
|
17
|
+
method.parameters.each do |kind, name|
|
10
18
|
unless supplier.respond_to?(name)
|
11
|
-
raise
|
19
|
+
raise ActionHandler::ActionArgumentError.new(
|
20
|
+
method,
|
21
|
+
"parameter #{name} is not defined in #{supplier}",
|
22
|
+
)
|
12
23
|
end
|
13
24
|
|
14
|
-
|
25
|
+
case kind
|
26
|
+
when :req
|
27
|
+
values << supplier.send(name, *supplier_args)
|
28
|
+
when :keyreq
|
29
|
+
keywords[name] = supplier.send(name, *supplier_args)
|
30
|
+
when :opt, :key
|
31
|
+
raise ActionHandler::ActionArgumentError.new(method, <<~ERR)
|
32
|
+
Do not use optional arguments.
|
33
|
+
ActionHandler always injects arguments even if the value is nil,
|
34
|
+
so the optional values never be used.
|
35
|
+
ERR
|
36
|
+
when :rest, :keyrest
|
37
|
+
raise ActionHandler::ActionArgumentError.new(
|
38
|
+
method,
|
39
|
+
'rest arguments cannot be used',
|
40
|
+
)
|
41
|
+
end
|
15
42
|
end
|
43
|
+
|
44
|
+
values << keywords unless keywords.empty?
|
45
|
+
values
|
16
46
|
end
|
17
47
|
end
|
18
48
|
end
|
@@ -14,24 +14,16 @@ module ActionHandler
|
|
14
14
|
handler_class.instance_variable_set(CONFIG_VAR_NAME, config)
|
15
15
|
end
|
16
16
|
|
17
|
-
attr_reader :as_controller
|
18
17
|
attr_reader :action_methods
|
19
18
|
attr_reader :args_suppliers
|
20
19
|
attr_reader :custom_args
|
21
20
|
|
22
21
|
def initialize
|
23
|
-
@as_controller = nil
|
24
22
|
@action_methods = nil
|
25
23
|
@args_suppliers = []
|
26
24
|
@custom_args = {} # { method_name: proc }
|
27
25
|
end
|
28
26
|
|
29
|
-
def as_controller=(block)
|
30
|
-
raise ArgumentError, 'must be proc' unless block.is_a?(Proc)
|
31
|
-
|
32
|
-
@as_controller = block
|
33
|
-
end
|
34
|
-
|
35
27
|
def action_methods=(names)
|
36
28
|
raise ArgumentError, 'must be array' unless names.is_a?(Array)
|
37
29
|
|
@@ -10,9 +10,8 @@ module ActionHandler
|
|
10
10
|
end
|
11
11
|
|
12
12
|
module ControllerExtension
|
13
|
-
def use_handler
|
14
|
-
|
15
|
-
ActionHandler::Installer.new.install(handler, self)
|
13
|
+
def use_handler(&block)
|
14
|
+
ActionHandler::Installer.new.install(self, &block)
|
16
15
|
end
|
17
16
|
end
|
18
17
|
end
|
data/lib/action_handler/equip.rb
CHANGED
@@ -35,10 +35,6 @@ module ActionHandler
|
|
35
35
|
end
|
36
36
|
|
37
37
|
module HandlerExtension
|
38
|
-
def as_controller(&block)
|
39
|
-
ActionHandler::Config.get(self).as_controller = block
|
40
|
-
end
|
41
|
-
|
42
38
|
def action_methods(*method_names)
|
43
39
|
ActionHandler::Config.get(self).action_methods = method_names
|
44
40
|
end
|
@@ -3,6 +3,11 @@
|
|
3
3
|
require 'action_handler/args_maker'
|
4
4
|
require 'action_handler/response_evaluator'
|
5
5
|
|
6
|
+
# TODO: Add `controller_send` (to use controller methods like `send_data`)
|
7
|
+
|
8
|
+
# It is better if there is a way to return streaming response.
|
9
|
+
# (`self.response_body = ` or `response.stream.write`?)
|
10
|
+
|
6
11
|
module ActionHandler
|
7
12
|
class Installer
|
8
13
|
attr_reader :args_maker
|
@@ -16,23 +21,37 @@ module ActionHandler
|
|
16
21
|
@res_evaluator = res_evaluator
|
17
22
|
end
|
18
23
|
|
19
|
-
def install(
|
20
|
-
|
24
|
+
def install(ctrl_class, &block)
|
25
|
+
ctrl_class.instance_variable_set(:@_action_handler_factory, block)
|
26
|
+
|
27
|
+
installer = self
|
28
|
+
initializer = Module.new.tap do |m|
|
29
|
+
m.define_method(:initialize) do |*args|
|
30
|
+
super(*args)
|
31
|
+
factory = self.class.instance_variable_get(:@_action_handler_factory)
|
32
|
+
handler = factory.call(self)
|
33
|
+
installer.send(:setup, self, handler)
|
34
|
+
end
|
35
|
+
end
|
21
36
|
|
22
|
-
ctrl_class.
|
37
|
+
ctrl_class.prepend initializer
|
38
|
+
end
|
39
|
+
|
40
|
+
private def setup(ctrl, handler)
|
41
|
+
config = ActionHandler::Config.get(handler.class) || ActionHandler::Config.new
|
23
42
|
|
24
43
|
actions = action_methods(handler, config)
|
25
44
|
args_supplier = args_supplier(config)
|
26
45
|
|
27
46
|
actions.each do |name|
|
28
47
|
installer = self
|
29
|
-
|
48
|
+
|
49
|
+
# If we use `define_singleton_method`, methods don't work correctly.
|
50
|
+
# I don't know Rails internal details but
|
51
|
+
# Rails requires methods to be defined in a class.
|
52
|
+
ctrl.class.define_method(name) do
|
30
53
|
method = handler.method(name)
|
31
|
-
args = installer.args_maker.make_args(
|
32
|
-
method.parameters,
|
33
|
-
args_supplier,
|
34
|
-
context: self,
|
35
|
-
)
|
54
|
+
args = installer.args_maker.make_args(method, args_supplier, context: self)
|
36
55
|
res = method.call(*args)
|
37
56
|
installer.res_evaluator.evaluate(self, res)
|
38
57
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: action_handler
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- ryym
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-
|
11
|
+
date: 2018-12-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rspec
|
@@ -85,7 +85,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
85
85
|
requirements:
|
86
86
|
- - ">="
|
87
87
|
- !ruby/object:Gem::Version
|
88
|
-
version: '
|
88
|
+
version: '2.3'
|
89
89
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
90
90
|
requirements:
|
91
91
|
- - ">="
|