activeinteractor 0.1.3 → 0.1.4

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5ce2748cbf2a6f2584dbcb73cfce3347d2bd9447e7f02af34bb99d488c50e117
4
- data.tar.gz: c5c088b60da0c26ddab97fa8f9c033375e6ef95e2aff17363c3f828b2df433dc
3
+ metadata.gz: 7f7136d8728ef016a9041ff462d8874af56028432ab839e8b7dab707b3ad1c59
4
+ data.tar.gz: 04f08a4985a45385885b165f26fb65a93f9952ea4d2c0849312d5ff63075770a
5
5
  SHA512:
6
- metadata.gz: aa6e94e75c3470d0e3807c0caf4802ec543613d731bde0c8d693943ebe594ec91538a28bc29fbb43ed738da9d6705c97211301bb4294e902e2c43fa50f543d05
7
- data.tar.gz: 437b0c0e527018c101610d2f7731130cfd8f2df62627242a6ec6ed24430427473501c72429ef53378892ce6155704bc7b0665d243c8fe4a49d1d3dad27fb0c13
6
+ metadata.gz: a6148b98fb26e34891e81fa84243f21d4db8460be907f69bae1a082ebce941ae3112c031aaba03086bba52b729fe358833b3a5fcbabb7e5fad505f29114eca6c
7
+ data.tar.gz: daa7e71d54dfd86195e0487ef4f0da05df2cd3a47e4067e520a86876d87492dd04bcc406157214c55434404d82dfb5c4358adc24546e6f7e60998d6e2f562a9a
data/CHANGELOG.md CHANGED
@@ -7,24 +7,30 @@ and this project adheres to [Semantic Versioning].
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [v0.1.4] - 2019-04-12
11
+
12
+ ### Added
13
+
14
+ - [#28] The ability to alias attributes on interactor contexts.
15
+
10
16
  ## [v0.1.3] - 2019-04-01
11
17
 
12
18
  ### Added
13
19
 
14
- - #25: Implement `each_perform` callbacks on organizers
20
+ - [#25] Implement `each_perform` callbacks on organizers
15
21
 
16
22
  ## [v0.1.2] - 2019-04-01
17
23
 
18
24
  ### Added
19
25
 
20
- - #22: Allow the directory interactors are generated in to be configurable
26
+ - [#22] Allow the directory interactors are generated in to be configurable
21
27
 
22
28
  ## [v0.1.1] - 2019-03-30
23
29
 
24
30
  ### Fixed
25
31
 
26
- - #15: `NameError` (uninitialized constant `ActiveInteractor::Organizer`)
27
- - #16: `NoMethodError` (undefined method `merge` for `ActiveInteractor::Context::Base`)
32
+ - [#15] `NameError` (uninitialized constant `ActiveInteractor::Organizer`)
33
+ - [#16] `NoMethodError` (undefined method `merge` for `ActiveInteractor::Context::Base`)
28
34
 
29
35
  ## v0.1.0 - 2019-03-30
30
36
 
@@ -33,7 +39,18 @@ and this project adheres to [Semantic Versioning].
33
39
  [Keep a Changelog]: https://keepachangelog.com/en/1.0.0/
34
40
  [Semantic Versioning]: https://semver.org/spec/v2.0.0.html
35
41
 
36
- [Unreleased]: https://github.com/aaronmallen/activeinteractor/compare/v0.1.3..HEAD
42
+ <!-- versions -->
43
+
44
+ [Unreleased]: https://github.com/aaronmallen/activeinteractor/compare/v0.1.4..HEAD
45
+ [v0.1.4]: https://github.com/aaronmallen/activeinteractor/compare/v0.1.3...v0.1.4
37
46
  [v0.1.3]: https://github.com/aaronmallen/activeinteractor/compare/v0.1.2...v0.1.3
38
47
  [v0.1.2]: https://github.com/aaronmallen/activeinteractor/compare/v0.1.1...v0.1.2
39
48
  [v0.1.1]: https://github.com/aaronmallen/activeinteractor/compare/v0.1.0...v0.1.1
49
+
50
+ <!-- pull requests and issues -->
51
+
52
+ [#15]: https://github.com/aaronmallen/activeinteractor/pull/15
53
+ [#16]: https://github.com/aaronmallen/activeinteractor/pull/16
54
+ [#22]: https://github.com/aaronmallen/activeinteractor/pull/22
55
+ [#25]: https://github.com/aaronmallen/activeinteractor/pull/25
56
+ [#28]: https://github.com/aaronmallen/activeinteractor/pull/28
data/README.md CHANGED
@@ -8,7 +8,7 @@
8
8
  [![Maintainability](https://img.shields.io/codeclimate/maintainability/aaronmallen/activeinteractor.svg?maxAge=300&style=for-the-badge)](https://codeclimate.com/github/aaronmallen/activeinteractor/maintainability)
9
9
  [![Test Coverage](https://img.shields.io/codeclimate/coverage/aaronmallen/activeinteractor.svg?maxAge=300&style=for-the-badge)](https://codeclimate.com/github/aaronmallen/activeinteractor/test_coverage)
10
10
 
11
- Ruby interactors with [ActiveModel::Validations] based on the [interactors][collective_idea_interactors] gem.
11
+ Ruby interactors with [ActiveModel::Validations] based on the [interactor][collective_idea_interactors] gem.
12
12
 
13
13
  ## Getting Started
14
14
 
@@ -178,6 +178,38 @@ context.clean! #=> { occupation: 'Software Dude' }
178
178
  context.occupation #=> nil
179
179
  ```
180
180
 
181
+ #### Aliasing Attributes
182
+
183
+ Some times you may want to use the same interactor functionality with different
184
+ model types having different naming conventions for similar attributes. We can
185
+ inform the interactors context of these aliases with the `context_attribute_aliases`
186
+ method on our interactors.
187
+
188
+ ```ruby
189
+ class MyInteractor < ActiveInteractor::Base
190
+ context_attributes :first_name, :last_name
191
+ context_attribute_aliases last_name: :sir_name
192
+ end
193
+
194
+ context = MyInteractor.perform(first_name: 'Aaron', sir_name: 'Allen')
195
+ # => <#MyInteractor::Context first_name='Aaron', last_name='Allen'
196
+ ```
197
+
198
+ We can also pass an array of aliases to the attribute like this:
199
+
200
+ ```ruby
201
+ class MyInteractor < ActiveInteractor::Base
202
+ context_attributes :first_name, :last_name
203
+ context_attribute_aliases last_name: %i[sir_name sirname]
204
+ end
205
+
206
+ context = MyInteractor.perform(first_name: 'Aaron', sir_name: 'Allen')
207
+ # => <#MyInteractor::Context first_name='Aaron', last_name='Allen'
208
+
209
+ context = MyInteractor.perform(first_name: 'Aaron', sirname: 'Allen')
210
+ # => <#MyInteractor::Context first_name='Aaron', last_name='Allen'
211
+ ```
212
+
181
213
  #### Validating the Context
182
214
 
183
215
  `ActiveInteractor` delegates all the validation methods provided by [ActiveModel::Validations]
@@ -460,7 +492,10 @@ context.rollback!
460
492
  "Done"
461
493
  ```
462
494
 
463
- We can do worker before `perform` is invoked on each interactor in an [Organizer](#organizers) with the `before_each_perform` method:
495
+ #### Organizer Callbacks
496
+
497
+ We can do worker before `perform` is invoked on each interactor in an [Organizer](#organizers)
498
+ with the `before_each_perform` method:
464
499
 
465
500
  ```ruby
466
501
  class MyInteractor1 < ActiveInteractor::Base
@@ -499,7 +534,8 @@ MyOrganizer.perform(name: 'Aaron')
499
534
  #=> <MyOrganizer::Context name='Aaron'>
500
535
  ```
501
536
 
502
- We can do worker around `perform` is invokation on each interactor in an [Organizer](#organizers) with the `around_each_perform` method:
537
+ We can do worker around `perform` is invokation on each interactor in an [Organizer](#organizers)
538
+ with the `around_each_perform` method:
503
539
 
504
540
  ```ruby
505
541
  class MyInteractor1 < ActiveInteractor::Base
@@ -542,7 +578,8 @@ MyOrganizer.perform(name: 'Aaron')
542
578
  #=> <MyOrganizer::Context name='Aaron'>
543
579
  ```
544
580
 
545
- We can do worker after `perform` is invoked on each interactor in an [Organizer](#organizers) with the `after_each_perform` method:
581
+ We can do worker after `perform` is invoked on each interactor in an [Organizer](#organizers)
582
+ with the `after_each_perform` method:
546
583
 
547
584
  ```ruby
548
585
  class MyInteractor1 < ActiveInteractor::Base
@@ -1,8 +1,9 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'active_support/core_ext/class/attribute'
4
3
  require 'ostruct'
5
4
 
5
+ Dir[File.expand_path('context/*.rb', __dir__)].each { |file| require file }
6
+
6
7
  module ActiveInteractor
7
8
  # ActiveInteractor::Context module
8
9
  #
@@ -10,35 +11,14 @@ module ActiveInteractor
10
11
  # @since 0.0.1
11
12
  # @version 0.1
12
13
  module Context
13
- # Raised when an interactor context fails
14
- #
15
- # @author Aaron Allen <hello@aaronmallen.me>
16
- # @since 0.0.1
17
- # @version 0.1
18
- #
19
- # @!attribute [r] context
20
- # @return [Base] an instance of {Base}
21
- class Failure < StandardError
22
- attr_reader :context
23
-
24
- # A new instance of {Failure}
25
- # @param context [Hash] an instance of {Base}
26
- # @return [Failure] a new instance of {Failure}
27
- def initialize(context = {})
28
- @context = context
29
- super
30
- end
31
- end
32
-
33
14
  # The base context class inherited by all {Interactor::Context} classes
34
15
  #
35
16
  # @author Aaron Allen <hello@aaronmallen.me>
36
17
  # @since 0.0.1
37
- # @version 0.1
18
+ # @version 0.2
38
19
  class Base < OpenStruct
39
20
  include ActiveModel::Validations
40
-
41
- class_attribute :__default_attributes, instance_writer: false, default: []
21
+ include Attributes
42
22
 
43
23
  # A new instance of {Base}
44
24
  # @param interactor [ActiveInteractor::Base] an interactor instance
@@ -50,66 +30,6 @@ module ActiveInteractor
50
30
  super(attributes)
51
31
  end
52
32
 
53
- class << self
54
- # Attributes defined on the context class
55
- #
56
- # @example Get attributes defined on a context class
57
- # MyInteractor::Context.attributes
58
- # #=> [:first_name, :last_name]
59
- #
60
- # @return [Array<Symbol>] the defined attributes
61
- def attributes
62
- __default_attributes
63
- .concat(_validate_callbacks.map(&:filter).map(&:attributes).flatten)
64
- .flatten
65
- .uniq
66
- end
67
-
68
- # Set attributes on a context class
69
- # @param [Array<Symbol, String>] attributes
70
- #
71
- # @example Define attributes on a context class
72
- # MyInteractor::Context.attributes = :first_name, :last_name
73
- # #=> [:first_name, :last_name]
74
- #
75
- # @return [Array<Symbol>] the defined attributes
76
- def attributes=(*attributes)
77
- self.__default_attributes = self.attributes.concat(attributes.flatten.map(&:to_sym)).uniq
78
- end
79
- end
80
-
81
- # Attributes defined on the instance
82
- #
83
- # @example Get attributes defined on an instance
84
- # MyInteractor::Context.attributes = :first_name, :last_name
85
- # #=> [:first_name, :last_name]
86
- #
87
- # context = MyInteractor::Context.new(first_name: 'Aaron', last_name: 'Allen')
88
- # #=> <#MyInteractor::Context first_name='Aaron', last_name='Allen'>
89
- #
90
- # context.attributes
91
- # #=> { first_name: 'Aaron', last_name: 'Allen' }
92
- #
93
- # @example Get attributes defined on an instance with unknown attribute
94
- # MyInteractor::Context.attributes = :first_name, :last_name
95
- # #=> [:first_name, :last_name]
96
- #
97
- # context = MyInteractor::Context.new(first_name: 'Aaron', last_name: 'Allen', unknown: 'unknown')
98
- # #=> <#MyInteractor::Context first_name='Aaron', last_name='Allen', unknown='unknown'>
99
- #
100
- # context.attributes
101
- # #=> { first_name: 'Aaron', last_name: 'Allen' }
102
- #
103
- # context.unknown
104
- # #=> 'unknown'
105
- #
106
- # @return [Hash{Symbol => *}] the defined attributes and values
107
- def attributes
108
- self.class.attributes.each_with_object({}) do |attribute, hash|
109
- hash[attribute] = self[attribute] if self[attribute]
110
- end
111
- end
112
-
113
33
  # Track that an Interactor has been called. The {#called!} method
114
34
  # is used by the interactor being invoked with this context. After an
115
35
  # interactor is successfully called, the interactor instance is tracked in
@@ -120,37 +40,6 @@ module ActiveInteractor
120
40
  _called << interactor
121
41
  end
122
42
 
123
- # Removes properties from the instance that are not
124
- # explicitly defined in the context instance {#attributes}
125
- #
126
- # @example Clean an instance of Context with unknown attribute
127
- # MyInteractor::Context.attributes = :first_name, :last_name
128
- # #=> [:first_name, :last_name]
129
- #
130
- # context = MyInteractor::Context.new(first_name: 'Aaron', last_name: 'Allen', unknown: 'unknown')
131
- # #=> <#MyInteractor::Context first_name='Aaron', last_name='Allen', unknown='unknown'>
132
- #
133
- # context.unknown
134
- # #=> 'unknown'
135
- #
136
- # context.clean!
137
- # #=> { unknown: 'unknown' }
138
- #
139
- # context.unknown
140
- # #=> nil
141
- #
142
- # @return [Hash{Symbol => *}] the deleted attributes
143
- def clean!
144
- deleted = {}
145
- return deleted if keys.empty?
146
-
147
- keys.reject { |key| self.class.attributes.include?(key) }.each do |attribute|
148
- deleted[attribute] = self[attribute] if self[attribute]
149
- delete_field(key.to_s)
150
- end
151
- deleted
152
- end
153
-
154
43
  # Fail the context instance. Failing a context raises an error
155
44
  # that may be rescued by the calling interactor. The context is also flagged
156
45
  # as having failed
@@ -195,23 +84,6 @@ module ActiveInteractor
195
84
  end
196
85
  alias fail? failure?
197
86
 
198
- # All keys of properties currently defined on the instance
199
- #
200
- # @example An instance of Context with unknown attribute
201
- # MyInteractor::Context.attributes = :first_name, :last_name
202
- # #=> [:first_name, :last_name]
203
- #
204
- # context = MyInteractor::Context.new(first_name: 'Aaron', last_name: 'Allen', unknown: 'unknown')
205
- # #=> <#MyInteractor::Context first_name='Aaron', last_name='Allen', unknown='unknown'>
206
- #
207
- # context.keys
208
- # #=> [:first_name, :last_name, :unknown]
209
- #
210
- # @return [Array<Symbol>] keys defined on the instance
211
- def keys
212
- each_pair.map { |pair| pair[0].to_sym }
213
- end
214
-
215
87
  # Attempt to call the interactor for missing validation callback methods
216
88
  # @raise [NameError] if the method is not a validation callback or method
217
89
  # does not exist on the interactor instance
@@ -295,6 +167,4 @@ module ActiveInteractor
295
167
  end
296
168
  end
297
169
  end
298
-
299
- Dir[File.expand_path('context/*.rb', __dir__)].each { |file| require file }
300
170
  end
@@ -0,0 +1,194 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'active_support/core_ext/array/wrap'
4
+ require 'active_support/core_ext/class/attribute'
5
+
6
+ module ActiveInteractor
7
+ # ActiveInteractor::Context module
8
+ #
9
+ # @author Aaron Allen <hello@aaronmallen.me>
10
+ # @since 0.0.1
11
+ # @version 0.1
12
+ module Context
13
+ # Provides Context Attribute methods to included classes
14
+ #
15
+ # @author Aaron Allen <hello@aaronmallen.me>
16
+ # @since 0.1.4
17
+ # @version 0.1
18
+ module Attributes
19
+ extend ActiveSupport::Concern
20
+
21
+ included do
22
+ extend ClassMethods
23
+ class_attribute :__default_attributes, instance_writer: false, default: []
24
+ end
25
+
26
+ module ClassMethods
27
+ # Attributes defined on the context class
28
+ #
29
+ # @example Get attributes defined on a context class
30
+ # MyInteractor::Context.attributes
31
+ # #=> [:first_name, :last_name]
32
+ #
33
+ # @return [Array<Symbol>] the defined attributes
34
+ def attributes
35
+ __default_attributes
36
+ .concat(_validate_callbacks.map(&:filter).map(&:attributes).flatten)
37
+ .flatten
38
+ .uniq
39
+ end
40
+
41
+ # Set attributes on a context class
42
+ #
43
+ # @param attributes [Array<Symbol, String>] the attributes of the context
44
+ #
45
+ # @example Define attributes on a context class
46
+ # MyInteractor::Context.attributes = :first_name, :last_name
47
+ # #=> [:first_name, :last_name]
48
+ #
49
+ # @return [Array<Symbol>] the defined attributes
50
+ def attributes=(*attributes)
51
+ self.__default_attributes = self.attributes.concat(attributes.flatten.map(&:to_sym)).uniq
52
+ end
53
+
54
+ # Attribute aliases defined on the context class
55
+ #
56
+ # @example Get attribute aliases defined on a context class
57
+ # MyInteractor::Context.attribute_aliases
58
+ # #=> { last_name: [:sir_name] }
59
+ #
60
+ # @return [Hash{Symbol => Array<Symbol>}]
61
+ def attribute_aliases
62
+ @attribute_aliases ||= {}
63
+ end
64
+
65
+ # Set attribute aliases on the context class
66
+ #
67
+ # @param aliases [Hash{Symbol => Symbol, Array<Symbol>}] the attribute aliases of
68
+ # the context
69
+ #
70
+ # @return [Hash{Symbol => Array<Symbol>}]
71
+ def alias_attributes(aliases = {})
72
+ map_attribute_aliases(aliases)
73
+ attribute_aliases
74
+ end
75
+
76
+ private
77
+
78
+ def map_attribute_aliases(aliases)
79
+ aliases.each_key do |attribute|
80
+ key = attribute.to_sym
81
+ attribute_aliases[key] ||= []
82
+ attribute_aliases[key].concat(Array.wrap(aliases[attribute]).map(&:to_sym))
83
+ end
84
+ end
85
+ end
86
+
87
+ def initialize(attributes = {})
88
+ super(map_attributes(attributes))
89
+ end
90
+
91
+ # Attributes defined on the instance
92
+ #
93
+ # @example Get attributes defined on an instance
94
+ # MyInteractor::Context.attributes = :first_name, :last_name
95
+ # #=> [:first_name, :last_name]
96
+ #
97
+ # context = MyInteractor::Context.new(first_name: 'Aaron', last_name: 'Allen')
98
+ # #=> <#MyInteractor::Context first_name='Aaron', last_name='Allen'>
99
+ #
100
+ # context.attributes
101
+ # #=> { first_name: 'Aaron', last_name: 'Allen' }
102
+ #
103
+ # @example Get attributes defined on an instance with unknown attribute
104
+ # MyInteractor::Context.attributes = :first_name, :last_name
105
+ # #=> [:first_name, :last_name]
106
+ #
107
+ # context = MyInteractor::Context.new(first_name: 'Aaron', last_name: 'Allen', unknown: 'unknown')
108
+ # #=> <#MyInteractor::Context first_name='Aaron', last_name='Allen', unknown='unknown'>
109
+ #
110
+ # context.attributes
111
+ # #=> { first_name: 'Aaron', last_name: 'Allen' }
112
+ #
113
+ # context.unknown
114
+ # #=> 'unknown'
115
+ #
116
+ # @return [Hash{Symbol => *}] the defined attributes and values
117
+ def attributes
118
+ self.class.attributes.each_with_object({}) do |attribute, hash|
119
+ hash[attribute] = self[attribute] if self[attribute]
120
+ end
121
+ end
122
+
123
+ # Removes properties from the instance that are not
124
+ # explicitly defined in the context instance {#attributes}
125
+ #
126
+ # @example Clean an instance of Context with unknown attribute
127
+ # MyInteractor::Context.attributes = :first_name, :last_name
128
+ # #=> [:first_name, :last_name]
129
+ #
130
+ # context = MyInteractor::Context.new(first_name: 'Aaron', last_name: 'Allen', unknown: 'unknown')
131
+ # #=> <#MyInteractor::Context first_name='Aaron', last_name='Allen', unknown='unknown'>
132
+ #
133
+ # context.unknown
134
+ # #=> 'unknown'
135
+ #
136
+ # context.clean!
137
+ # #=> { unknown: 'unknown' }
138
+ #
139
+ # context.unknown
140
+ # #=> nil
141
+ #
142
+ # @return [Hash{Symbol => *}] the deleted attributes
143
+ def clean!
144
+ deleted = {}
145
+ return deleted if keys.empty?
146
+
147
+ keys.reject { |key| self.class.attributes.include?(key) }.each do |attribute|
148
+ deleted[attribute] = self[attribute] if self[attribute]
149
+ delete_field(key.to_s)
150
+ end
151
+ deleted
152
+ end
153
+
154
+ # All keys of properties currently defined on the instance
155
+ #
156
+ # @example An instance of Context with unknown attribute
157
+ # MyInteractor::Context.attributes = :first_name, :last_name
158
+ # #=> [:first_name, :last_name]
159
+ #
160
+ # context = MyInteractor::Context.new(first_name: 'Aaron', last_name: 'Allen', unknown: 'unknown')
161
+ # #=> <#MyInteractor::Context first_name='Aaron', last_name='Allen', unknown='unknown'>
162
+ #
163
+ # context.keys
164
+ # #=> [:first_name, :last_name, :unknown]
165
+ #
166
+ # @return [Array<Symbol>] keys defined on the instance
167
+ def keys
168
+ each_pair.map { |pair| pair[0].to_sym }
169
+ end
170
+
171
+ private
172
+
173
+ def aliased_key(key)
174
+ self.class.attribute_aliases.each_pair do |attribute, aliases|
175
+ key = aliases.any? { |aliased| aliased == key.to_sym } ? attribute : key.to_sym
176
+ end
177
+ key
178
+ end
179
+
180
+ def map_attributes(attributes)
181
+ return {} unless attributes
182
+
183
+ attributes.keys.each_with_object({}) do |attribute, hash|
184
+ key = aliased_key(attribute)
185
+ hash[key] = attributes[attribute]
186
+ end
187
+ end
188
+
189
+ def new_ostruct_member!(name)
190
+ super(aliased_key(name))
191
+ end
192
+ end
193
+ end
194
+ end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveInteractor
4
+ module Context
5
+ # Raised when an interactor context fails
6
+ #
7
+ # @author Aaron Allen <hello@aaronmallen.me>
8
+ # @since 0.0.1
9
+ # @version 0.2
10
+ #
11
+ # @!attribute [r] context
12
+ # @return [Base] an instance of {Base}
13
+ class Failure < StandardError
14
+ attr_reader :context
15
+
16
+ # A new instance of {Failure}
17
+ # @param context [ActiveInteractor::Context::Base] an
18
+ # instance of {ActiveInteractor::Context::Base}
19
+ # @return [Failure] a new instance of {Failure}
20
+ def initialize(context = nil)
21
+ @context = context
22
+ super
23
+ end
24
+ end
25
+ end
26
+ end
@@ -81,7 +81,7 @@ module ActiveInteractor
81
81
  @should_clean_context.nil? && self.class.__clean_after_perform
82
82
  end
83
83
 
84
- # Skip {ActiveInteractor::Context::Base#clean! #clean! on an interactor
84
+ # Skip {ActiveInteractor::Context::Attributes#clean! #clean! on an interactor
85
85
  # context that calls the {Callbacks.clean_context_on_completion} class method.
86
86
  # This method is meant to be invoked by organizer interactors
87
87
  # to ensure contexts are approriately passed between interactors.
@@ -7,7 +7,7 @@ module ActiveInteractor
7
7
  # @api private
8
8
  # @author Aaron Allen <hello@aaronmallen.me>
9
9
  # @since 0.0.1
10
- # @version 0.1
10
+ # @version 0.2
11
11
  module Context
12
12
  extend ActiveSupport::Concern
13
13
 
@@ -42,6 +42,43 @@ module ActiveInteractor
42
42
  context_class.attributes = attributes
43
43
  end
44
44
 
45
+ # Assign attribute aliases to the context class of the interactor
46
+ # any aliases passed to the context will be assigned to the
47
+ # key of the aliases hash
48
+ #
49
+ # @example Assign attribute aliases to the context class
50
+ # class MyInteractor > ActiveInteractor::Base
51
+ # context_attributes :first_name, :last_name
52
+ # context_attribute_aliases last_name: :sir_name
53
+ # end
54
+ #
55
+ # MyInteractor::Context.attribute_aliases
56
+ # #=> { last_name: [:sir_name] }
57
+ #
58
+ # class MyInteractor > ActiveInteractor::Base
59
+ # context_attributes :first_name, :last_name
60
+ # context_attribute_aliases last_name: %i[sir_name, sirname]
61
+ # end
62
+ #
63
+ # MyInteractor::Context.attribute_aliases
64
+ # #=> { last_name: [:sir_name, :sirname] }
65
+ #
66
+ # context = MyInteractor.perform(first_name: 'Aaron', sir_name: 'Allen')
67
+ # #=> <#MyInteractor::Context first_name='Aaron', last_name='Allen')
68
+ #
69
+ # context.sir_name
70
+ # #=> nil
71
+ #
72
+ # context.last_name
73
+ # #=> 'Allen'
74
+ #
75
+ # @param aliases [Hash{Symbol => Symbol, Array<Symbol>}] the attribute aliases
76
+ #
77
+ # @return [Hash{Symbol => Array<Symbol>}] the attribute aliases
78
+ def context_attribute_aliases(aliases = {})
79
+ context_class.alias_attributes(aliases)
80
+ end
81
+
45
82
  # The context class of the interactor
46
83
  #
47
84
  # @example
@@ -3,5 +3,5 @@
3
3
  module ActiveInteractor
4
4
  # The ActiveInteractor gem version
5
5
  # @return [String] the gem version
6
- VERSION = '0.1.3'
6
+ VERSION = '0.1.4'
7
7
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: activeinteractor
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.3
4
+ version: 0.1.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Aaron Allen
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-04-01 00:00:00.000000000 Z
11
+ date: 2019-04-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activemodel
@@ -220,6 +220,8 @@ files:
220
220
  - lib/active_interactor/base.rb
221
221
  - lib/active_interactor/configuration.rb
222
222
  - lib/active_interactor/context.rb
223
+ - lib/active_interactor/context/attributes.rb
224
+ - lib/active_interactor/context/errors.rb
223
225
  - lib/active_interactor/interactor.rb
224
226
  - lib/active_interactor/interactor/callbacks.rb
225
227
  - lib/active_interactor/interactor/context.rb
@@ -244,10 +246,10 @@ licenses:
244
246
  - MIT
245
247
  metadata:
246
248
  bug_tracker_uri: https://github.com/aaronmallen/activeinteractor/issues
247
- changelog_uri: https://github.com/aaronmallen/activeinteractor/blob/v0.1.3/CHANGELOG.md
248
- documentation_uri: https://www.rubydoc.info/gems/activeinteractor/0.1.3
249
+ changelog_uri: https://github.com/aaronmallen/activeinteractor/blob/v0.1.4/CHANGELOG.md
250
+ documentation_uri: https://www.rubydoc.info/gems/activeinteractor/0.1.4
249
251
  hompage_uri: https://github.com/aaronmallen/activeinteractor
250
- source_code_uri: https://github.com/aaronmallen/activeinteractor/tree/v0.1.3
252
+ source_code_uri: https://github.com/aaronmallen/activeinteractor/tree/v0.1.4
251
253
  wiki_uri: https://github.com/aaronmallen/activeinteractor/wiki
252
254
  post_install_message:
253
255
  rdoc_options: []