active_interaction 0.10.2 → 1.0.0
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 +14 -1
- data/README.md +32 -35
- data/lib/active_interaction.rb +14 -6
- data/lib/active_interaction/base.rb +155 -135
- data/lib/active_interaction/concerns/active_modelable.rb +46 -0
- data/lib/active_interaction/{modules/overload_hash.rb → concerns/hashable.rb} +5 -1
- data/lib/active_interaction/concerns/missable.rb +47 -0
- data/lib/active_interaction/concerns/runnable.rb +156 -0
- data/lib/active_interaction/errors.rb +50 -14
- data/lib/active_interaction/filter.rb +33 -45
- data/lib/active_interaction/filters/abstract_date_time_filter.rb +24 -15
- data/lib/active_interaction/filters/abstract_filter.rb +18 -0
- data/lib/active_interaction/filters/abstract_numeric_filter.rb +13 -8
- data/lib/active_interaction/filters/array_filter.rb +42 -35
- data/lib/active_interaction/filters/boolean_filter.rb +8 -11
- data/lib/active_interaction/filters/date_filter.rb +11 -15
- data/lib/active_interaction/filters/date_time_filter.rb +11 -15
- data/lib/active_interaction/filters/file_filter.rb +11 -11
- data/lib/active_interaction/filters/float_filter.rb +7 -15
- data/lib/active_interaction/filters/hash_filter.rb +18 -24
- data/lib/active_interaction/filters/integer_filter.rb +7 -14
- data/lib/active_interaction/filters/model_filter.rb +13 -14
- data/lib/active_interaction/filters/string_filter.rb +11 -14
- data/lib/active_interaction/filters/symbol_filter.rb +6 -9
- data/lib/active_interaction/filters/time_filter.rb +13 -16
- data/lib/active_interaction/modules/validation.rb +9 -4
- data/lib/active_interaction/version.rb +5 -2
- data/spec/active_interaction/base_spec.rb +109 -4
- data/spec/active_interaction/{modules/active_model_spec.rb → concerns/active_modelable_spec.rb} +15 -3
- data/spec/active_interaction/{modules/overload_hash_spec.rb → concerns/hashable_spec.rb} +2 -3
- data/spec/active_interaction/{modules/method_missing_spec.rb → concerns/missable_spec.rb} +38 -3
- data/spec/active_interaction/concerns/runnable_spec.rb +192 -0
- data/spec/active_interaction/filters/abstract_filter_spec.rb +8 -0
- data/spec/active_interaction/filters/abstract_numeric_filter_spec.rb +1 -1
- data/spec/active_interaction/modules/validation_spec.rb +2 -2
- data/spec/support/concerns.rb +15 -0
- data/spec/support/filters.rb +5 -5
- data/spec/support/interactions.rb +6 -5
- metadata +47 -73
- data/lib/active_interaction/filters.rb +0 -28
- data/lib/active_interaction/modules/active_model.rb +0 -32
- data/lib/active_interaction/modules/core.rb +0 -70
- data/lib/active_interaction/modules/method_missing.rb +0 -20
- data/spec/active_interaction/filters_spec.rb +0 -23
- data/spec/active_interaction/modules/core_spec.rb +0 -114
@@ -0,0 +1,46 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
module ActiveInteraction
|
4
|
+
# Implement the minimal ActiveModel interface.
|
5
|
+
#
|
6
|
+
# @private
|
7
|
+
module ActiveModelable
|
8
|
+
extend ActiveSupport::Concern
|
9
|
+
|
10
|
+
include ActiveModel::Conversion
|
11
|
+
include ActiveModel::Validations
|
12
|
+
|
13
|
+
extend ActiveModel::Naming
|
14
|
+
|
15
|
+
# @return (see ClassMethods#i18n_scope)
|
16
|
+
#
|
17
|
+
# @see ActiveModel::Translation#i18n_scope
|
18
|
+
def i18n_scope
|
19
|
+
self.class.i18n_scope
|
20
|
+
end
|
21
|
+
|
22
|
+
# @return [Boolean]
|
23
|
+
#
|
24
|
+
# @see ActiveRecord::Presistence#new_record?
|
25
|
+
def new_record?
|
26
|
+
true
|
27
|
+
end
|
28
|
+
|
29
|
+
# @return [Boolean]
|
30
|
+
#
|
31
|
+
# @see ActiveRecord::Presistence#persisted?
|
32
|
+
def persisted?
|
33
|
+
false
|
34
|
+
end
|
35
|
+
|
36
|
+
#
|
37
|
+
module ClassMethods
|
38
|
+
# @return [Symbol]
|
39
|
+
#
|
40
|
+
# @see ActiveModel::Translation#i18n_scope
|
41
|
+
def i18n_scope
|
42
|
+
:active_interaction
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -1,8 +1,12 @@
|
|
1
1
|
# coding: utf-8
|
2
2
|
|
3
3
|
module ActiveInteraction
|
4
|
+
# Allow `hash` to be overridden when given arguments and/or a block.
|
5
|
+
#
|
4
6
|
# @private
|
5
|
-
module
|
7
|
+
module Hashable
|
8
|
+
extend ActiveSupport::Concern
|
9
|
+
|
6
10
|
def hash(*args, &block)
|
7
11
|
if args.empty? && !block_given?
|
8
12
|
super
|
@@ -0,0 +1,47 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
module ActiveInteraction
|
4
|
+
# Handle common `method_missing` functionality.
|
5
|
+
#
|
6
|
+
# @private
|
7
|
+
module Missable
|
8
|
+
extend ActiveSupport::Concern
|
9
|
+
|
10
|
+
# @param slug [Symbol]
|
11
|
+
#
|
12
|
+
# @yield [klass, args, options]
|
13
|
+
#
|
14
|
+
# @yieldparam klass [Class]
|
15
|
+
# @yieldparam args [Array]
|
16
|
+
# @yieldparam options [Hash]
|
17
|
+
#
|
18
|
+
# @return [Missable]
|
19
|
+
def method_missing(slug, *args, &block)
|
20
|
+
return super unless (klass = filter(slug))
|
21
|
+
|
22
|
+
options = args.last.is_a?(Hash) ? args.pop : {}
|
23
|
+
|
24
|
+
yield(klass, args, options) if block_given?
|
25
|
+
|
26
|
+
self
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
# @param slug [Symbol]
|
32
|
+
#
|
33
|
+
# @return [Filter, nil]
|
34
|
+
def filter(slug)
|
35
|
+
Filter.factory(slug)
|
36
|
+
rescue MissingFilterError
|
37
|
+
nil
|
38
|
+
end
|
39
|
+
|
40
|
+
# @param slug [Symbol]
|
41
|
+
#
|
42
|
+
# @return [Boolean]
|
43
|
+
def respond_to_missing?(slug, *)
|
44
|
+
!!filter(slug)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,156 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
begin
|
4
|
+
require 'active_record'
|
5
|
+
rescue LoadError
|
6
|
+
module ActiveRecord
|
7
|
+
#
|
8
|
+
class Base
|
9
|
+
def self.transaction(*)
|
10
|
+
yield
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
module ActiveInteraction
|
17
|
+
# @abstract Include and override {#execute} to implement a custom Runnable
|
18
|
+
# class.
|
19
|
+
#
|
20
|
+
# @note Must be included after `ActiveModel::Validations`.
|
21
|
+
#
|
22
|
+
# Runs code in transactions and only provides the result if there are no
|
23
|
+
# validation errors.
|
24
|
+
#
|
25
|
+
# @private
|
26
|
+
module Runnable
|
27
|
+
extend ActiveSupport::Concern
|
28
|
+
include ActiveModel::Validations
|
29
|
+
|
30
|
+
included do
|
31
|
+
validate :runtime_errors
|
32
|
+
end
|
33
|
+
|
34
|
+
# @return [Errors]
|
35
|
+
def errors
|
36
|
+
@_interaction_errors
|
37
|
+
end
|
38
|
+
|
39
|
+
# @abstract
|
40
|
+
#
|
41
|
+
# @raise [NotImplementedError]
|
42
|
+
def execute
|
43
|
+
fail NotImplementedError
|
44
|
+
end
|
45
|
+
|
46
|
+
# @return [Object] If there are no validation errors.
|
47
|
+
# @return [nil] If there are validation errors.
|
48
|
+
def result
|
49
|
+
@_interaction_result
|
50
|
+
end
|
51
|
+
|
52
|
+
# @param result [Object]
|
53
|
+
#
|
54
|
+
# @return (see #result)
|
55
|
+
def result=(result)
|
56
|
+
if errors.empty?
|
57
|
+
@_interaction_result = result
|
58
|
+
@_interaction_runtime_errors = nil
|
59
|
+
else
|
60
|
+
@_interaction_result = nil
|
61
|
+
@_interaction_runtime_errors = errors.dup
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
# @return [Boolean]
|
66
|
+
def valid?(*)
|
67
|
+
super || (self.result = nil)
|
68
|
+
end
|
69
|
+
|
70
|
+
private
|
71
|
+
|
72
|
+
# @param other [Class] The other interaction.
|
73
|
+
# @param (see ClassMethods.run)
|
74
|
+
#
|
75
|
+
# @return (see #result)
|
76
|
+
#
|
77
|
+
# @raise [Interrupt]
|
78
|
+
def compose(other, *args)
|
79
|
+
outcome = other.run(*args)
|
80
|
+
|
81
|
+
if outcome.valid?
|
82
|
+
outcome.result
|
83
|
+
else
|
84
|
+
fail Interrupt, outcome
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
# @return (see #result=)
|
89
|
+
# @return [nil]
|
90
|
+
def run
|
91
|
+
return unless valid?
|
92
|
+
|
93
|
+
self.result = ActiveRecord::Base.transaction do
|
94
|
+
begin
|
95
|
+
execute
|
96
|
+
rescue Interrupt => interrupt
|
97
|
+
interrupt.outcome.errors.full_messages.each do |message|
|
98
|
+
errors.add(:base, message) unless errors.added?(:base, message)
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
# @return [Object]
|
105
|
+
#
|
106
|
+
# @raise [InvalidInteractionError] If there are validation errors.
|
107
|
+
def run!
|
108
|
+
run
|
109
|
+
|
110
|
+
if valid?
|
111
|
+
result
|
112
|
+
else
|
113
|
+
fail InvalidInteractionError, errors.full_messages.join(', ')
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
# @!group Validations
|
118
|
+
|
119
|
+
def runtime_errors
|
120
|
+
if @_interaction_runtime_errors
|
121
|
+
errors.merge!(@_interaction_runtime_errors)
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
#
|
126
|
+
module ClassMethods
|
127
|
+
def new(*)
|
128
|
+
super.tap do |instance|
|
129
|
+
{
|
130
|
+
:@_interaction_errors => Errors.new(instance),
|
131
|
+
:@_interaction_result => nil,
|
132
|
+
:@_interaction_runtime_errors => nil
|
133
|
+
}.each do |symbol, obj|
|
134
|
+
instance.instance_variable_set(symbol, obj)
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
# @param (see Runnable#initialize)
|
140
|
+
#
|
141
|
+
# @return [Runnable]
|
142
|
+
def run(*args)
|
143
|
+
new(*args).tap { |instance| instance.send(:run) }
|
144
|
+
end
|
145
|
+
|
146
|
+
# @param (see Runnable#initialize)
|
147
|
+
#
|
148
|
+
# @return (see Runnable#run!)
|
149
|
+
#
|
150
|
+
# @raise (see Runnable#run!)
|
151
|
+
def run!(*args)
|
152
|
+
new(*args).send(:run!)
|
153
|
+
end
|
154
|
+
end
|
155
|
+
end
|
156
|
+
end
|
@@ -1,63 +1,90 @@
|
|
1
1
|
# coding: utf-8
|
2
2
|
|
3
|
-
#
|
3
|
+
#
|
4
4
|
module ActiveInteraction
|
5
5
|
# Top-level error class. All other errors subclass this.
|
6
|
+
#
|
7
|
+
# @return [Class]
|
6
8
|
Error = Class.new(StandardError)
|
7
9
|
|
8
10
|
# Raised if a class name is invalid.
|
11
|
+
#
|
12
|
+
# @return [Class]
|
9
13
|
InvalidClassError = Class.new(Error)
|
10
14
|
|
11
15
|
# Raised if a default value is invalid.
|
16
|
+
#
|
17
|
+
# @return [Class]
|
12
18
|
InvalidDefaultError = Class.new(Error)
|
13
19
|
|
14
20
|
# Raised if a filter has an invalid definition.
|
21
|
+
#
|
22
|
+
# @return [Class]
|
15
23
|
InvalidFilterError = Class.new(Error)
|
16
24
|
|
17
25
|
# Raised if an interaction is invalid.
|
26
|
+
#
|
27
|
+
# @return [Class]
|
18
28
|
InvalidInteractionError = Class.new(Error)
|
19
29
|
|
20
30
|
# Raised if a user-supplied value is invalid.
|
31
|
+
#
|
32
|
+
# @return [Class]
|
21
33
|
InvalidValueError = Class.new(Error)
|
22
34
|
|
23
35
|
# Raised if a filter cannot be found.
|
36
|
+
#
|
37
|
+
# @return [Class]
|
24
38
|
MissingFilterError = Class.new(Error)
|
25
39
|
|
26
40
|
# Raised if no value is given.
|
41
|
+
#
|
42
|
+
# @return [Class]
|
27
43
|
MissingValueError = Class.new(Error)
|
28
44
|
|
29
45
|
# Raised if there is no default value.
|
46
|
+
#
|
47
|
+
# @return [Class]
|
30
48
|
NoDefaultError = Class.new(Error)
|
31
49
|
|
50
|
+
# Used by {Runnable} to signal a failure when composing.
|
51
|
+
#
|
32
52
|
# @private
|
33
|
-
Interrupt
|
53
|
+
class Interrupt < Error
|
54
|
+
attr_reader :outcome
|
55
|
+
|
56
|
+
# @param outcome [Runnable]
|
57
|
+
def initialize(outcome)
|
58
|
+
super()
|
59
|
+
|
60
|
+
@outcome = outcome
|
61
|
+
end
|
62
|
+
end
|
34
63
|
private_constant :Interrupt
|
35
64
|
|
36
|
-
#
|
65
|
+
# An extension that provides symbolic error messages to make introspection
|
37
66
|
# and testing easier.
|
38
|
-
#
|
39
|
-
# @since 0.6.0
|
40
67
|
class Errors < ActiveModel::Errors
|
41
|
-
#
|
68
|
+
# Maps attributes to arrays of symbolic messages.
|
42
69
|
#
|
43
70
|
# @return [Hash{Symbol => Array<Symbol>}]
|
44
71
|
attr_reader :symbolic
|
45
72
|
|
46
73
|
# Adds a symbolic error message to an attribute.
|
47
74
|
#
|
48
|
-
# @
|
49
|
-
# @param symbol [Symbol] The symbolic error to add.
|
50
|
-
# @param message [String, Symbol, Proc]
|
51
|
-
# @param options [Hash]
|
52
|
-
#
|
53
|
-
# @example Adding a symbolic error.
|
75
|
+
# @example
|
54
76
|
# errors.add_sym(:attribute)
|
55
77
|
# errors.symbolic
|
56
78
|
# # => {:attribute=>[:invalid]}
|
57
79
|
# errors.messages
|
58
80
|
# # => {:attribute=>["is invalid"]}
|
59
81
|
#
|
60
|
-
# @
|
82
|
+
# @param attribute [Symbol] The attribute to add an error to.
|
83
|
+
# @param symbol [Symbol, nil] The symbolic error to add.
|
84
|
+
# @param message [String, Symbol, Proc, nil] The message to add.
|
85
|
+
# @param options [Hash]
|
86
|
+
#
|
87
|
+
# @return (see #symbolic)
|
61
88
|
#
|
62
89
|
# @see ActiveModel::Errors#add
|
63
90
|
def add_sym(attribute, symbol = :invalid, message = nil, options = {})
|
@@ -67,21 +94,30 @@ module ActiveInteraction
|
|
67
94
|
symbolic[attribute] << symbol
|
68
95
|
end
|
69
96
|
|
97
|
+
# @see ActiveModel::Errors#initialize
|
98
|
+
#
|
70
99
|
# @private
|
71
|
-
def initialize(*
|
100
|
+
def initialize(*)
|
72
101
|
@symbolic = {}.with_indifferent_access
|
102
|
+
|
73
103
|
super
|
74
104
|
end
|
75
105
|
|
106
|
+
# @see ActiveModel::Errors#initialize_dup
|
107
|
+
#
|
76
108
|
# @private
|
77
109
|
def initialize_dup(other)
|
78
110
|
@symbolic = other.symbolic.with_indifferent_access
|
111
|
+
|
79
112
|
super
|
80
113
|
end
|
81
114
|
|
115
|
+
# @see ActiveModel::Errors#clear
|
116
|
+
#
|
82
117
|
# @private
|
83
118
|
def clear
|
84
119
|
symbolic.clear
|
120
|
+
|
85
121
|
super
|
86
122
|
end
|
87
123
|
|
@@ -4,15 +4,13 @@ require 'active_support/inflector'
|
|
4
4
|
|
5
5
|
module ActiveInteraction
|
6
6
|
# @!macro [new] filter_method_params
|
7
|
-
# @param *attributes [Array<Symbol>]
|
7
|
+
# @param *attributes [Array<Symbol>] Attributes to create.
|
8
8
|
# @param options [Hash{Symbol => Object}]
|
9
9
|
#
|
10
|
-
# @option options [Object] :default
|
11
|
-
# @option options [String] :desc
|
10
|
+
# @option options [Object] :default Fallback value if `nil` is given.
|
11
|
+
# @option options [String] :desc Human-readable description of this input.
|
12
12
|
|
13
13
|
# Describes an input filter for an interaction.
|
14
|
-
#
|
15
|
-
# @since 0.6.0
|
16
14
|
class Filter
|
17
15
|
# @return [Regexp]
|
18
16
|
CLASS_REGEXP = /\AActiveInteraction::([A-Z]\w*)Filter\z/
|
@@ -22,7 +20,7 @@ module ActiveInteraction
|
|
22
20
|
CLASSES = {}
|
23
21
|
private_constant :CLASSES
|
24
22
|
|
25
|
-
# @return [
|
23
|
+
# @return [Hash{Symbol => Filter}]
|
26
24
|
attr_reader :filters
|
27
25
|
|
28
26
|
# @return [Symbol]
|
@@ -31,10 +29,6 @@ module ActiveInteraction
|
|
31
29
|
# @return [Hash{Symbol => Object}]
|
32
30
|
attr_reader :options
|
33
31
|
|
34
|
-
# Filters that allow sub-filters, like arrays and hashes, must be able to
|
35
|
-
# use `hash` as a part of their DSL. To keep things consistent, `hash` is
|
36
|
-
# undefined on all filters. Realistically, {#name} should be unique
|
37
|
-
# enough to use in place of {#hash}.
|
38
32
|
undef_method :hash
|
39
33
|
|
40
34
|
class << self
|
@@ -43,7 +37,6 @@ module ActiveInteraction
|
|
43
37
|
# @example
|
44
38
|
# ActiveInteraction::Filter.factory(:boolean)
|
45
39
|
# # => ActiveInteraction::BooleanFilter
|
46
|
-
#
|
47
40
|
# @example
|
48
41
|
# ActiveInteraction::Filter.factory(:invalid)
|
49
42
|
# # => ActiveInteraction::MissingFilterError: :invalid
|
@@ -52,7 +45,7 @@ module ActiveInteraction
|
|
52
45
|
#
|
53
46
|
# @return [Class]
|
54
47
|
#
|
55
|
-
# @raise [MissingFilterError]
|
48
|
+
# @raise [MissingFilterError] If the slug doesn't map to a filter.
|
56
49
|
#
|
57
50
|
# @see .slug
|
58
51
|
def factory(slug)
|
@@ -66,14 +59,13 @@ module ActiveInteraction
|
|
66
59
|
# @example
|
67
60
|
# ActiveInteraction::BooleanFilter.slug
|
68
61
|
# # => :boolean
|
69
|
-
#
|
70
62
|
# @example
|
71
63
|
# ActiveInteraction::Filter.slug
|
72
64
|
# # => ActiveInteraction::InvalidClassError: ActiveInteraction::Filter
|
73
65
|
#
|
74
66
|
# @return [Symbol]
|
75
67
|
#
|
76
|
-
# @raise [InvalidClassError]
|
68
|
+
# @raise [InvalidClassError] If the filter doesn't have a valid slug.
|
77
69
|
#
|
78
70
|
# @see .factory
|
79
71
|
def slug
|
@@ -82,6 +74,8 @@ module ActiveInteraction
|
|
82
74
|
match.captures.first.underscore.to_sym
|
83
75
|
end
|
84
76
|
|
77
|
+
# @param klass [Class]
|
78
|
+
#
|
85
79
|
# @private
|
86
80
|
def inherited(klass)
|
87
81
|
CLASSES[klass.slug] = klass
|
@@ -93,11 +87,11 @@ module ActiveInteraction
|
|
93
87
|
# @param name [Symbol]
|
94
88
|
# @param options [Hash{Symbol => Object}]
|
95
89
|
#
|
96
|
-
# @option options [Object] :default
|
90
|
+
# @option options [Object] :default Fallback value to use when given `nil`.
|
97
91
|
def initialize(name, options = {}, &block)
|
98
92
|
@name = name
|
99
93
|
@options = options.dup
|
100
|
-
@filters =
|
94
|
+
@filters = {}
|
101
95
|
|
102
96
|
instance_eval(&block) if block_given?
|
103
97
|
end
|
@@ -108,29 +102,22 @@ module ActiveInteraction
|
|
108
102
|
# @example
|
109
103
|
# ActiveInteraction::Filter.new(:example).clean(nil)
|
110
104
|
# # => ActiveInteraction::MissingValueError: example
|
111
|
-
#
|
112
105
|
# @example
|
113
106
|
# ActiveInteraction::Filter.new(:example).clean(0)
|
114
107
|
# # => ActiveInteraction::InvalidValueError: example: 0
|
115
|
-
#
|
116
108
|
# @example
|
117
109
|
# ActiveInteraction::Filter.new(:example, default: nil).clean(nil)
|
118
110
|
# # => nil
|
119
|
-
#
|
120
111
|
# @example
|
121
112
|
# ActiveInteraction::Filter.new(:example, default: 0).clean(nil)
|
122
|
-
# # => ActiveInteraction::
|
113
|
+
# # => ActiveInteraction::InvalidDefaultError: example: 0
|
123
114
|
#
|
124
115
|
# @param value [Object]
|
125
116
|
#
|
126
117
|
# @return [Object]
|
127
118
|
#
|
128
|
-
# @raise
|
129
|
-
# @raise [MissingValueError] if the value is missing and the input is
|
130
|
-
# required
|
119
|
+
# @raise (see #cast)
|
131
120
|
# @raise (see #default)
|
132
|
-
#
|
133
|
-
# @see #default
|
134
121
|
def clean(value)
|
135
122
|
value = cast(value)
|
136
123
|
if value.nil?
|
@@ -143,23 +130,21 @@ module ActiveInteraction
|
|
143
130
|
# Get the default value.
|
144
131
|
#
|
145
132
|
# @example
|
133
|
+
# ActiveInteraction::Filter.new(:example).default
|
134
|
+
# # => ActiveInteraction::NoDefaultError: example
|
135
|
+
# @example
|
146
136
|
# ActiveInteraction::Filter.new(:example, default: nil).default
|
147
137
|
# # => nil
|
148
|
-
#
|
149
138
|
# @example
|
150
139
|
# ActiveInteraction::Filter.new(:example, default: 0).default
|
151
140
|
# # => ActiveInteraction::InvalidDefaultError: example: 0
|
152
141
|
#
|
153
|
-
# @example
|
154
|
-
# ActiveInteraction::Filter.new(:example).default
|
155
|
-
# # => ActiveInteraction::NoDefaultError: example
|
156
|
-
#
|
157
142
|
# @return [Object]
|
158
143
|
#
|
159
|
-
# @raise [
|
160
|
-
# @raise [
|
144
|
+
# @raise [NoDefaultError] If the default is missing.
|
145
|
+
# @raise [InvalidDefaultError] If the default is invalid.
|
161
146
|
def default
|
162
|
-
fail NoDefaultError, name unless
|
147
|
+
fail NoDefaultError, name unless default?
|
163
148
|
|
164
149
|
cast(options[:default])
|
165
150
|
rescue InvalidValueError, MissingValueError
|
@@ -169,12 +154,10 @@ module ActiveInteraction
|
|
169
154
|
# Get the description.
|
170
155
|
#
|
171
156
|
# @example
|
172
|
-
# ActiveInteraction::Filter.new(:example, desc: '
|
173
|
-
# # => "
|
174
|
-
#
|
175
|
-
# @return [String, nil] the description
|
157
|
+
# ActiveInteraction::Filter.new(:example, desc: 'Description!').desc
|
158
|
+
# # => "Description!"
|
176
159
|
#
|
177
|
-
# @
|
160
|
+
# @return [String, nil]
|
178
161
|
def desc
|
179
162
|
options[:desc]
|
180
163
|
end
|
@@ -182,25 +165,30 @@ module ActiveInteraction
|
|
182
165
|
# Tells if this filter has a default value.
|
183
166
|
#
|
184
167
|
# @example
|
185
|
-
#
|
186
|
-
# filter.has_default?
|
168
|
+
# ActiveInteraction::Filter.new(:example).default?
|
187
169
|
# # => false
|
188
|
-
#
|
189
170
|
# @example
|
190
|
-
#
|
191
|
-
# filter.has_default?
|
171
|
+
# ActiveInteraction::Filter.new(:example, default: nil).default?
|
192
172
|
# # => true
|
193
173
|
#
|
194
174
|
# @return [Boolean]
|
195
|
-
def
|
175
|
+
def default?
|
196
176
|
options.key?(:default)
|
197
177
|
end
|
198
178
|
|
179
|
+
# @param value [Object]
|
180
|
+
#
|
181
|
+
# @return [Object]
|
182
|
+
#
|
183
|
+
# @raise [MissingValueError] If the value is missing and there is no
|
184
|
+
# default.
|
185
|
+
# @raise [InvalidValueError] If the value is invalid.
|
186
|
+
#
|
199
187
|
# @private
|
200
188
|
def cast(value)
|
201
189
|
case value
|
202
190
|
when NilClass
|
203
|
-
fail MissingValueError, name unless
|
191
|
+
fail MissingValueError, name unless default?
|
204
192
|
|
205
193
|
nil
|
206
194
|
else
|