active_interaction 0.10.2 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|