activeduty 0.1.0 → 0.1.1
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 +17 -0
- data/README.md +155 -1
- data/lib/active_duty/callbacks.rb +13 -6
- data/lib/active_duty/initializers.rb +89 -17
- data/lib/active_duty/version.rb +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2b879bfa0f660945b57f5b87a67ddef1bf55dd91fdece4c5dc07820d93950d90
|
4
|
+
data.tar.gz: 13c31dbba265e4d3e738a417595633deee7e837e23eaff04b5154b3f299ca77a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8833e8338c11c2cc0c398485268e0d3947079c3b109efc071ee025018e03959b051a6c2b9d4d44b00550071536816aaa9be6d68b7376773654425a7fdc4773e1
|
7
|
+
data.tar.gz: 44b5d6e28ab6ba25f9fd150a9b9df4f3f3ca670a33bd39d426e01b107688ab3aaa94dca3c20165503f995d9ea2571cb0ef969cb5da19e4845ef6adbcd91a2f5d
|
data/CHANGELOG.md
ADDED
data/README.md
CHANGED
@@ -1,3 +1,157 @@
|
|
1
1
|
# ActiveDuty
|
2
2
|
|
3
|
-
Service objects.
|
3
|
+
Service objects, based loosely on [Interactor](https://github.com/collectiveidea/interactor).
|
4
|
+
|
5
|
+
## Design
|
6
|
+
|
7
|
+
Define the logic in `run` and call it with `call`:
|
8
|
+
|
9
|
+
## Basic usage
|
10
|
+
|
11
|
+
```ruby
|
12
|
+
class AuthenticateUser < ActiveDuty::Base
|
13
|
+
def initialize(email, password)
|
14
|
+
@email, @password = email, password
|
15
|
+
end
|
16
|
+
|
17
|
+
def run
|
18
|
+
if user = User.authenticate(@email, @password)
|
19
|
+
context.user = user
|
20
|
+
else
|
21
|
+
fail!
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
```
|
26
|
+
|
27
|
+
Usage:
|
28
|
+
|
29
|
+
```
|
30
|
+
service = AuthenticateUser.new("josh@example.com", password: "password")
|
31
|
+
service.call
|
32
|
+
if service.success?
|
33
|
+
# do something
|
34
|
+
else
|
35
|
+
puts service.errors.inspect
|
36
|
+
end
|
37
|
+
```
|
38
|
+
|
39
|
+
## Advanced usage
|
40
|
+
|
41
|
+
### init_with
|
42
|
+
|
43
|
+
A DSL for initializing.
|
44
|
+
|
45
|
+
#### Ordered arguments
|
46
|
+
|
47
|
+
```
|
48
|
+
class AuthenticateUser < ActiveDuty::Base
|
49
|
+
init_with :username, :password
|
50
|
+
end
|
51
|
+
```
|
52
|
+
|
53
|
+
Is the equivalent of:
|
54
|
+
|
55
|
+
```
|
56
|
+
class AuthenticateUser < ActiveDuty::Base
|
57
|
+
attr_reader :username, :password
|
58
|
+
def initialize(username, password)
|
59
|
+
@username, @password = username, password
|
60
|
+
end
|
61
|
+
end
|
62
|
+
```
|
63
|
+
|
64
|
+
#### Keyword arguments
|
65
|
+
|
66
|
+
```
|
67
|
+
class AuthenticateUser < ActiveDuty::Base
|
68
|
+
init_with uname: :username, pw: :password
|
69
|
+
end
|
70
|
+
```
|
71
|
+
|
72
|
+
Is the equivalent of:
|
73
|
+
|
74
|
+
```
|
75
|
+
class AuthenticateUser < ActiveDuty::Base
|
76
|
+
attr_reader :username, :password
|
77
|
+
def initialize(uname:, pw:)
|
78
|
+
@username, @password = uname, pw
|
79
|
+
end
|
80
|
+
end
|
81
|
+
```
|
82
|
+
|
83
|
+
#### Defaults
|
84
|
+
|
85
|
+
```
|
86
|
+
class AuthenticateUser < ActiveDuty::Base
|
87
|
+
init_with :username, [:password, nil]
|
88
|
+
end
|
89
|
+
```
|
90
|
+
|
91
|
+
Is the equivalent of:
|
92
|
+
|
93
|
+
```
|
94
|
+
class AuthenticateUser < ActiveDuty::Base
|
95
|
+
attr_reader :username, :password
|
96
|
+
def initialize(username, password = nil)
|
97
|
+
@username, @password = username, password
|
98
|
+
end
|
99
|
+
end
|
100
|
+
```
|
101
|
+
|
102
|
+
#### Keyword arguments
|
103
|
+
|
104
|
+
```
|
105
|
+
class AuthenticateUser < ActiveDuty::Base
|
106
|
+
init_with uname: [nil, :username], pw: ["good-password", :password]
|
107
|
+
end
|
108
|
+
```
|
109
|
+
|
110
|
+
Is the equivalent of:
|
111
|
+
|
112
|
+
```
|
113
|
+
class AuthenticateUser < ActiveDuty::Base
|
114
|
+
attr_reader :username, :password
|
115
|
+
def initialize(uname: nil, pw: "good-password")
|
116
|
+
@username, @password = uname, pw
|
117
|
+
end
|
118
|
+
end
|
119
|
+
```
|
120
|
+
|
121
|
+
### Callbacks
|
122
|
+
|
123
|
+
Supports `after_initialize`, `before_call`, `after_call`. They use `ActiveModel::Callbacks` under the hood, so the API is familiar.
|
124
|
+
|
125
|
+
### Context
|
126
|
+
|
127
|
+
An `OpenStruct` for a setting information during the runtime of your service object. Exposed via `context`.
|
128
|
+
|
129
|
+
### Errors
|
130
|
+
|
131
|
+
Uses `ActiveModel::Errors` under the hood.
|
132
|
+
|
133
|
+
### Rollbacks
|
134
|
+
|
135
|
+
If your call fails and you need to do some housekeeping, define a rollback:
|
136
|
+
|
137
|
+
```ruby
|
138
|
+
class AuthenticateUser < ActiveDuty::Base
|
139
|
+
def rollback
|
140
|
+
# do something
|
141
|
+
end
|
142
|
+
end
|
143
|
+
```
|
144
|
+
|
145
|
+
Or class-level:
|
146
|
+
|
147
|
+
```ruby
|
148
|
+
class AuthenticateUser < ActiveDuty::Base
|
149
|
+
rollback do
|
150
|
+
# do something
|
151
|
+
end
|
152
|
+
end
|
153
|
+
```
|
154
|
+
|
155
|
+
### Failing
|
156
|
+
|
157
|
+
Need to fail? Call `fail!`
|
@@ -6,20 +6,27 @@ module ActiveDuty
|
|
6
6
|
define_model_callbacks :call, only: [:before, :after, :around]
|
7
7
|
|
8
8
|
def self.after_initialize(&block)
|
9
|
-
@
|
9
|
+
@_after_initialize_callbacks ||= []
|
10
|
+
@_after_initialize_callbacks << block
|
10
11
|
end
|
11
12
|
|
12
|
-
def self.
|
13
|
-
if defined?(@
|
14
|
-
@
|
13
|
+
def self._after_initialize_callbacks
|
14
|
+
if defined?(@_after_initialize_callbacks)
|
15
|
+
@_after_initialize_callbacks
|
15
16
|
else
|
16
17
|
nil
|
17
18
|
end
|
18
19
|
end
|
19
20
|
|
20
21
|
def after_initialize!
|
21
|
-
if self.class.
|
22
|
-
|
22
|
+
if self.class._after_initialize_callbacks
|
23
|
+
self.class._after_initialize_callbacks.each do |callback|
|
24
|
+
if callback.is_a?(Symbol)
|
25
|
+
send(callback)
|
26
|
+
else
|
27
|
+
instance_exec(self, &callback)
|
28
|
+
end
|
29
|
+
end
|
23
30
|
end
|
24
31
|
end
|
25
32
|
end
|
@@ -4,28 +4,100 @@ module ActiveDuty
|
|
4
4
|
module ClassMethods
|
5
5
|
def init_with(*args)
|
6
6
|
kwargs = args.extract_options!
|
7
|
-
|
8
7
|
if kwargs.empty?
|
9
|
-
|
10
|
-
|
11
|
-
|
8
|
+
init_from_ordered(args)
|
9
|
+
else
|
10
|
+
init_from_kw(kwargs)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
private
|
15
|
+
|
16
|
+
# initialize from ordered arguments
|
17
|
+
#
|
18
|
+
# init_with :username, :password
|
19
|
+
# def initialize(username, password)
|
20
|
+
# @username = username
|
21
|
+
# @password = password
|
22
|
+
#
|
23
|
+
# init_with [:username], [:password, nil], [:email, "no email"], [:options, {}]
|
24
|
+
# def initialize(username, password = nil, email: "no email", options = {})
|
25
|
+
# @username = username
|
26
|
+
# @password = password
|
27
|
+
# @email = email
|
28
|
+
# @options = options
|
29
|
+
def init_from_ordered(args)
|
30
|
+
init_string = []
|
31
|
+
args.each do |arg|
|
32
|
+
str = ""
|
33
|
+
if arg.is_a?(Array)
|
34
|
+
if arg.size == 2
|
35
|
+
if arg[1].is_a?(String)
|
36
|
+
str << "#{arg[0]} = \"#{arg[1]}\""
|
37
|
+
else
|
38
|
+
str << "#{arg[0]} = #{arg[1]}"
|
39
|
+
end
|
40
|
+
else
|
41
|
+
str << "#{arg[0]}"
|
12
42
|
end
|
13
|
-
|
43
|
+
else
|
44
|
+
str << "#{arg}"
|
14
45
|
end
|
15
|
-
|
16
|
-
class_eval <<-METHOD, __FILE__, __LINE__ + 1
|
17
|
-
def initialize(#{kwargs.keys.map { |key| "#{key}:" }.join(', ')})
|
18
|
-
#{kwargs.map { |key, value|
|
19
|
-
"
|
20
|
-
instance_variable_set(:\"@#{value}\", #{key})
|
21
|
-
self.class.attr_reader :#{value}
|
22
|
-
"
|
23
|
-
}.join("\n")
|
24
|
-
}
|
25
|
-
end
|
26
|
-
METHOD
|
46
|
+
init_string << str
|
27
47
|
end
|
48
|
+
class_eval <<-METHOD, __FILE__, __LINE__ + 1
|
49
|
+
def initialize(#{init_string.join(', ')})
|
50
|
+
#{args.map { |arg|
|
51
|
+
if arg.is_a?(Array)
|
52
|
+
"instance_variable_set(:\"@#{arg[0]}\", #{arg[0]})
|
53
|
+
self.class.attr_reader :#{arg[0]}"
|
54
|
+
else
|
55
|
+
"instance_variable_set(:\"@#{arg}\", #{arg})
|
56
|
+
self.class.attr_reader :#{arg}"
|
57
|
+
end
|
58
|
+
}.join("\n")
|
59
|
+
}
|
60
|
+
end
|
61
|
+
METHOD
|
62
|
+
end
|
63
|
+
|
64
|
+
# Initialize with keyword args.
|
65
|
+
#
|
66
|
+
# { username: :user } will
|
67
|
+
# def initialize(username:)
|
68
|
+
# @user = username
|
69
|
+
#
|
70
|
+
# { username: ["Bob", :user] } will
|
71
|
+
# def initialize(username: "Bob")
|
72
|
+
# @user = username
|
73
|
+
def init_from_kw(args)
|
28
74
|
|
75
|
+
initializer_string = []
|
76
|
+
args.each do |key, values|
|
77
|
+
str = "#{key}:"
|
78
|
+
if values.is_a?(Array) && values.size == 2
|
79
|
+
if values[0].is_a?(String)
|
80
|
+
str += " \"#{values[0]}\""
|
81
|
+
else
|
82
|
+
str += "#{values[0]}"
|
83
|
+
end
|
84
|
+
end
|
85
|
+
initializer_string << str
|
86
|
+
end
|
87
|
+
class_eval <<-METHOD, __FILE__, __LINE__ + 1
|
88
|
+
def initialize(#{initializer_string.join(', ')})
|
89
|
+
#{args.map { |key, values|
|
90
|
+
if values.is_a?(Array)
|
91
|
+
"instance_variable_set(:\"@#{values[1]}\", #{key})
|
92
|
+
self.class.attr_reader :#{values[1]}"
|
93
|
+
else
|
94
|
+
"instance_variable_set(:\"@#{values}\", #{key})
|
95
|
+
self.class.attr_reader :#{values}"
|
96
|
+
end
|
97
|
+
}.join("\n")
|
98
|
+
}
|
99
|
+
end
|
100
|
+
METHOD
|
29
101
|
end
|
30
102
|
|
31
103
|
end
|
data/lib/active_duty/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: activeduty
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Josh Brody
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-07-
|
11
|
+
date: 2020-07-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -86,6 +86,7 @@ executables: []
|
|
86
86
|
extensions: []
|
87
87
|
extra_rdoc_files: []
|
88
88
|
files:
|
89
|
+
- CHANGELOG.md
|
89
90
|
- README.md
|
90
91
|
- lib/active_duty.rb
|
91
92
|
- lib/active_duty/base.rb
|