active_interaction 1.6.1 → 2.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 +24 -5
- data/README.md +35 -32
- data/lib/active_interaction.rb +3 -4
- data/lib/active_interaction/backports.rb +47 -0
- data/lib/active_interaction/base.rb +8 -25
- data/lib/active_interaction/concerns/runnable.rb +4 -14
- data/lib/active_interaction/errors.rb +12 -82
- data/lib/active_interaction/filters/array_filter.rb +3 -9
- data/lib/active_interaction/filters/file_filter.rb +5 -24
- data/lib/active_interaction/filters/hash_filter.rb +6 -13
- data/lib/active_interaction/filters/interface_filter.rb +2 -2
- data/lib/active_interaction/filters/{model_filter.rb → object_filter.rb} +4 -5
- data/lib/active_interaction/locale/en.yml +0 -1
- data/lib/active_interaction/version.rb +1 -1
- data/spec/active_interaction/base_spec.rb +15 -14
- data/spec/active_interaction/concerns/runnable_spec.rb +2 -34
- data/spec/active_interaction/errors_spec.rb +5 -87
- data/spec/active_interaction/filters/array_filter_spec.rb +2 -2
- data/spec/active_interaction/filters/file_filter_spec.rb +4 -4
- data/spec/active_interaction/filters/hash_filter_spec.rb +1 -17
- data/spec/active_interaction/filters/{model_filter_spec.rb → object_filter_spec.rb} +17 -17
- data/spec/active_interaction/integration/array_interaction_spec.rb +10 -0
- data/spec/active_interaction/integration/hash_interaction_spec.rb +12 -2
- data/spec/active_interaction/integration/object_interaction_spec.rb +16 -0
- metadata +8 -11
- data/lib/active_interaction/concerns/transactable.rb +0 -81
- data/spec/active_interaction/concerns/transactable_spec.rb +0 -135
- data/spec/active_interaction/integration/model_interaction_spec.rb +0 -16
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ec03f8a492e5db88366e50b9a918ff40a4e008b3
|
4
|
+
data.tar.gz: 356b91990bfac14981a6d36dffcaafb4e3dd2d33
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a68094094d6dbf8a395a3f709ffd993944512c6edc921ce36f99b4383792de041954cc2d73271a0748102782f89c4e457bb63288ee56eb34e42ff6cb38fbcbd5
|
7
|
+
data.tar.gz: d682f33e94ea7bd25f4f9cf89e2fe3924bc501e608c6d32f469da42d92782f88aca01b43605c69adb5de62e36b2cafe3857307ff927a2306dbbb25ef334c4f93
|
data/CHANGELOG.md
CHANGED
@@ -1,8 +1,20 @@
|
|
1
|
-
# [
|
1
|
+
# [2.0.0][] (2015-05-06)
|
2
2
|
|
3
|
-
##
|
3
|
+
## Changed
|
4
|
+
|
5
|
+
- [#250][]: Replaced symbolic errors with Rails 5-style detailed errors.
|
6
|
+
- [#269][]: Prevented proc defaults from being eagerly evaluated.
|
7
|
+
- [#264][]: Renamed `model` filter to `object`.
|
8
|
+
- [#213][]: Remove transaction support. Database transactions will need to be
|
9
|
+
handled manually now.
|
10
|
+
- [#214][]: Results are returned from invalid outcomes.
|
11
|
+
- [#164][]: Changed the `hash` filter to use hashes with indifferent access.
|
12
|
+
- [#236][]: Changed the `file` filter to accept anything that responds to `eof?`.
|
13
|
+
|
14
|
+
## Security
|
4
15
|
|
5
|
-
- [#
|
16
|
+
- [#215][]: Rather than symbolizing keys all hashes now use indifferent access.
|
17
|
+
This takes care of potential but unlikely DoS attacks noted in [#163][].
|
6
18
|
|
7
19
|
# [1.6.0][] (2015-05-06)
|
8
20
|
|
@@ -402,7 +414,7 @@
|
|
402
414
|
|
403
415
|
- Initial release.
|
404
416
|
|
405
|
-
[
|
417
|
+
[2.0.0]: https://github.com/orgsync/active_interaction/compare/v1.6.0...v2.0.0
|
406
418
|
[1.6.0]: https://github.com/orgsync/active_interaction/compare/v1.5.1...v1.6.0
|
407
419
|
[1.5.1]: https://github.com/orgsync/active_interaction/compare/v1.5.0...v1.5.1
|
408
420
|
[1.5.0]: https://github.com/orgsync/active_interaction/compare/v1.4.1...v1.5.0
|
@@ -505,6 +517,7 @@
|
|
505
517
|
[#155]: https://github.com/orgsync/active_interaction/issues/155
|
506
518
|
[#156]: https://github.com/orgsync/active_interaction/issues/156
|
507
519
|
[#163]: https://github.com/orgsync/active_interaction/issues/163
|
520
|
+
[#164]: https://github.com/orgsync/active_interaction/issues/164
|
508
521
|
[#165]: https://github.com/orgsync/active_interaction/issues/165
|
509
522
|
[#173]: https://github.com/orgsync/active_interaction/issues/173
|
510
523
|
[#174]: https://github.com/orgsync/active_interaction/issues/174
|
@@ -517,11 +530,17 @@
|
|
517
530
|
[#203]: https://github.com/orgsync/active_interaction/issues/203
|
518
531
|
[#206]: https://github.com/orgsync/active_interaction/issues/206
|
519
532
|
[#207]: https://github.com/orgsync/active_interaction/issues/207
|
533
|
+
[#213]: https://github.com/orgsync/active_interaction/issues/213
|
534
|
+
[#214]: https://github.com/orgsync/active_interaction/issues/214
|
535
|
+
[#215]: https://github.com/orgsync/active_interaction/issues/215
|
520
536
|
[#224]: https://github.com/orgsync/active_interaction/issues/224
|
521
537
|
[#235]: https://github.com/orgsync/active_interaction/issues/235
|
538
|
+
[#236]: https://github.com/orgsync/active_interaction/issues/236
|
522
539
|
[#239]: https://github.com/orgsync/active_interaction/issues/239
|
523
540
|
[#244]: https://github.com/orgsync/active_interaction/issues/244
|
524
541
|
[#248]: https://github.com/orgsync/active_interaction/issues/248
|
542
|
+
[#250]: https://github.com/orgsync/active_interaction/issues/250
|
525
543
|
[#256]: https://github.com/orgsync/active_interaction/issues/256
|
544
|
+
[#264]: https://github.com/orgsync/active_interaction/issues/264
|
526
545
|
[#265]: https://github.com/orgsync/active_interaction/issues/265
|
527
|
-
[#
|
546
|
+
[#269]: https://github.com/orgsync/active_interaction/issues/269
|
data/README.md
CHANGED
@@ -39,7 +39,7 @@ Read more on [the project page][] or check out [the full documentation][].
|
|
39
39
|
- [File](#file)
|
40
40
|
- [Hash](#hash)
|
41
41
|
- [Interface](#interface)
|
42
|
-
- [
|
42
|
+
- [Object](#object)
|
43
43
|
- [String](#string)
|
44
44
|
- [Symbol](#symbol)
|
45
45
|
- [Dates and times](#dates-and-times)
|
@@ -75,13 +75,13 @@ Read more on [the project page][] or check out [the full documentation][].
|
|
75
75
|
Add it to your Gemfile:
|
76
76
|
|
77
77
|
``` rb
|
78
|
-
gem 'active_interaction', '~>
|
78
|
+
gem 'active_interaction', '~> 2.0'
|
79
79
|
```
|
80
80
|
|
81
81
|
Or install it manually:
|
82
82
|
|
83
83
|
``` sh
|
84
|
-
$ gem install active_interaction --version '~>
|
84
|
+
$ gem install active_interaction --version '~> 2.0'
|
85
85
|
```
|
86
86
|
|
87
87
|
This project uses [Semantic Versioning][]. Check out [the change log][] for a
|
@@ -124,8 +124,8 @@ end
|
|
124
124
|
Call `.run` on your interaction to execute it. You must pass a single hash to
|
125
125
|
`.run`. It will return an instance of your interaction. By convention, we call
|
126
126
|
this an outcome. You can use the `#valid?` method to ask the outcome if it's
|
127
|
-
valid. If it's invalid, take a look at its errors with `#errors`.
|
128
|
-
|
127
|
+
valid. If it's invalid, take a look at its errors with `#errors`. In either
|
128
|
+
case, the value returned from `#execute` will be stored in `#result`.
|
129
129
|
|
130
130
|
``` rb
|
131
131
|
outcome = Square.run(x: 'two point one')
|
@@ -379,11 +379,11 @@ InterfaceInteraction.run!(serializer: JSON)
|
|
379
379
|
# => "{\"is_json\":true}"
|
380
380
|
```
|
381
381
|
|
382
|
-
###
|
382
|
+
### Object
|
383
383
|
|
384
|
-
|
385
|
-
either `#is_a?` on the instance or `.===` on the class. Because of that,
|
386
|
-
also works with classes that have mixed modules in with `include`.
|
384
|
+
Object filters allow you to require an instance of a particular class. It
|
385
|
+
checks either `#is_a?` on the instance or `.===` on the class. Because of that,
|
386
|
+
it also works with classes that have mixed modules in with `include`.
|
387
387
|
|
388
388
|
``` rb
|
389
389
|
class Cow
|
@@ -392,17 +392,17 @@ class Cow
|
|
392
392
|
end
|
393
393
|
end
|
394
394
|
|
395
|
-
class
|
396
|
-
|
395
|
+
class ObjectInteraction < ActiveInteraction::Base
|
396
|
+
object :cow
|
397
397
|
|
398
398
|
def execute
|
399
399
|
cow.moo
|
400
400
|
end
|
401
401
|
end
|
402
402
|
|
403
|
-
|
404
|
-
# ActiveInteraction::InvalidInteractionError: Cow is not a valid
|
405
|
-
|
403
|
+
ObjectInteraction.run!(cow: Object.new)
|
404
|
+
# ActiveInteraction::InvalidInteractionError: Cow is not a valid object
|
405
|
+
ObjectInteraction.run!(cow: Cow.new)
|
406
406
|
# => "Moo!"
|
407
407
|
```
|
408
408
|
|
@@ -411,11 +411,11 @@ name is different than your class name, use the `class` option. It can be
|
|
411
411
|
either the class, a string, or a symbol.
|
412
412
|
|
413
413
|
``` rb
|
414
|
-
|
414
|
+
object :dolly1,
|
415
415
|
class: Sheep
|
416
|
-
|
416
|
+
object :dolly2,
|
417
417
|
class: 'Sheep'
|
418
|
-
|
418
|
+
object :dolly3,
|
419
419
|
class: :Sheep
|
420
420
|
```
|
421
421
|
|
@@ -788,7 +788,7 @@ spot.
|
|
788
788
|
|
789
789
|
``` rb
|
790
790
|
class DestroyAccount < ActiveInteraction::Base
|
791
|
-
|
791
|
+
object :account
|
792
792
|
|
793
793
|
def execute
|
794
794
|
account.destroy
|
@@ -822,7 +822,7 @@ Skip to [the predicates section](#predicates) for more information about them.
|
|
822
822
|
|
823
823
|
``` rb
|
824
824
|
class UpdateAccount < ActiveInteraction::Base
|
825
|
-
|
825
|
+
object :account
|
826
826
|
|
827
827
|
string :first_name, :last_name,
|
828
828
|
default: nil
|
@@ -1004,14 +1004,14 @@ end
|
|
1004
1004
|
|
1005
1005
|
### Errors
|
1006
1006
|
|
1007
|
-
ActiveInteraction provides
|
1008
|
-
of errors.
|
1007
|
+
ActiveInteraction provides detailed errors for easier introspection and testing
|
1008
|
+
of errors. Detailed errors improve on regular errors by adding a symbol that
|
1009
1009
|
represents the type of error that has occurred. Let's look at an example where
|
1010
1010
|
an item is purchased using a credit card.
|
1011
1011
|
|
1012
1012
|
``` rb
|
1013
1013
|
class BuyItem < ActiveInteraction::Base
|
1014
|
-
|
1014
|
+
object :credit_card, :item
|
1015
1015
|
hash :options do
|
1016
1016
|
boolean :gift_wrapped
|
1017
1017
|
end
|
@@ -1034,28 +1034,30 @@ errors.
|
|
1034
1034
|
``` rb
|
1035
1035
|
outcome = BuyItem.run(item: 'Thing', options: { gift_wrapped: 'yes' })
|
1036
1036
|
outcome.errors.messages
|
1037
|
-
# => {:credit_card=>["is required"], :item=>["is not a valid
|
1037
|
+
# => {:credit_card=>["is required"], :item=>["is not a valid object"], :options=>["has an invalid nested value (\"gift_wrapped\" => \"yes\")"]}
|
1038
1038
|
```
|
1039
1039
|
|
1040
1040
|
Determining the type of error based on the string is difficult if not
|
1041
|
-
impossible. Calling `#
|
1041
|
+
impossible. Calling `#details` instead of `#messages` on `errors` gives you
|
1042
1042
|
the same list of errors with a testable label representing the error.
|
1043
1043
|
|
1044
1044
|
``` rb
|
1045
|
-
outcome.errors.
|
1046
|
-
# => {
|
1045
|
+
outcome.errors.details
|
1046
|
+
# => {:credit_card=>[{:error=>:missing}], :item=>[{:type=>"object", :error=>:invalid_type}], :options=>[{:name=>"\"gift_wrapped\"", :value=>"\"yes\"", :error=>:invalid_nested}]}
|
1047
1047
|
```
|
1048
1048
|
|
1049
|
-
|
1050
|
-
|
1051
|
-
that the second argument is the error label.
|
1049
|
+
Detailed errors can also be manually added during the execute call by passing a
|
1050
|
+
symbol to `#add` instead of a string.
|
1052
1051
|
|
1053
1052
|
``` rb
|
1054
1053
|
def execute
|
1055
|
-
errors.
|
1054
|
+
errors.add(:monster, :no_passage)
|
1056
1055
|
end
|
1057
1056
|
```
|
1058
1057
|
|
1058
|
+
These types of errors will become standard with Rails 5. ActiveInteraction's
|
1059
|
+
implementation is based off of [active_model-errors_details][].
|
1060
|
+
|
1059
1061
|
ActiveInteraction also supports merging errors. This is useful if you want to
|
1060
1062
|
delegate validation to some other object. For example, if you have an
|
1061
1063
|
interaction that updates a record, you might want that record to validate
|
@@ -1063,7 +1065,7 @@ itself. By using the `#merge!` helper on `errors`, you can do exactly that.
|
|
1063
1065
|
|
1064
1066
|
``` rb
|
1065
1067
|
class UpdateThing < ActiveInteraction::Base
|
1066
|
-
|
1068
|
+
object :thing
|
1067
1069
|
|
1068
1070
|
def execute
|
1069
1071
|
unless thing.save
|
@@ -1180,7 +1182,7 @@ hsilgne:
|
|
1180
1182
|
hash: hsah
|
1181
1183
|
integer: regetni
|
1182
1184
|
interface: ecafretni
|
1183
|
-
|
1185
|
+
object: tcejbo
|
1184
1186
|
string: gnirts
|
1185
1187
|
symbol: lobmys
|
1186
1188
|
time: emit
|
@@ -1225,6 +1227,7 @@ Logo design by [Tyler Lee][].
|
|
1225
1227
|
[the full documentation]: http://rubydoc.info/github/orgsync/active_interaction
|
1226
1228
|
[semantic versioning]: http://semver.org/spec/v2.0.0.html
|
1227
1229
|
[the change log]: CHANGELOG.md
|
1230
|
+
[active_model-errors_details]: https://github.com/cowbell/active_model-errors_details
|
1228
1231
|
[aaron lasseigne]: https://github.com/AaronLasseigne
|
1229
1232
|
[taylor fausak]: https://github.com/tfausak
|
1230
1233
|
[orgsync]: https://github.com/orgsync
|
data/lib/active_interaction.rb
CHANGED
@@ -9,7 +9,7 @@ require 'active_model'
|
|
9
9
|
#
|
10
10
|
# @since 1.0.0
|
11
11
|
#
|
12
|
-
# @version
|
12
|
+
# @version 2.0.0
|
13
13
|
module ActiveInteraction
|
14
14
|
DEPRECATOR =
|
15
15
|
if ::ActiveSupport::Deprecation.respond_to?(:new)
|
@@ -31,7 +31,6 @@ require 'active_interaction/concerns/active_modelable'
|
|
31
31
|
require 'active_interaction/concerns/active_recordable'
|
32
32
|
require 'active_interaction/concerns/hashable'
|
33
33
|
require 'active_interaction/concerns/missable'
|
34
|
-
require 'active_interaction/concerns/transactable'
|
35
34
|
require 'active_interaction/concerns/runnable'
|
36
35
|
|
37
36
|
require 'active_interaction/grouped_input'
|
@@ -42,6 +41,7 @@ require 'active_interaction/modules/validation'
|
|
42
41
|
require 'active_interaction/filter_column'
|
43
42
|
require 'active_interaction/filter'
|
44
43
|
require 'active_interaction/filters/abstract_filter'
|
44
|
+
require 'active_interaction/filters/interface_filter'
|
45
45
|
require 'active_interaction/filters/abstract_date_time_filter'
|
46
46
|
require 'active_interaction/filters/abstract_numeric_filter'
|
47
47
|
require 'active_interaction/filters/array_filter'
|
@@ -53,8 +53,7 @@ require 'active_interaction/filters/file_filter'
|
|
53
53
|
require 'active_interaction/filters/float_filter'
|
54
54
|
require 'active_interaction/filters/hash_filter'
|
55
55
|
require 'active_interaction/filters/integer_filter'
|
56
|
-
require 'active_interaction/filters/
|
57
|
-
require 'active_interaction/filters/model_filter'
|
56
|
+
require 'active_interaction/filters/object_filter'
|
58
57
|
require 'active_interaction/filters/string_filter'
|
59
58
|
require 'active_interaction/filters/symbol_filter'
|
60
59
|
require 'active_interaction/filters/time_filter'
|
@@ -16,6 +16,53 @@ module ActiveInteraction
|
|
16
16
|
class Errors # rubocop:disable Style/Documentation
|
17
17
|
# Required for Rails < 3.2.13.
|
18
18
|
protected :initialize_dup
|
19
|
+
|
20
|
+
# Required for Rails < 5.
|
21
|
+
#
|
22
|
+
# Extracted from active_model-errors_details 1.2.0. Modified to add support
|
23
|
+
# for ActiveModel 3.2.0.
|
24
|
+
module Details
|
25
|
+
extend ActiveSupport::Concern
|
26
|
+
|
27
|
+
CALLBACKS_OPTIONS = ::ActiveModel::Errors::CALLBACKS_OPTIONS
|
28
|
+
private_constant :CALLBACKS_OPTIONS
|
29
|
+
|
30
|
+
included do
|
31
|
+
attr_reader :details
|
32
|
+
|
33
|
+
%w[initialize initialize_dup add clear delete].each do |method|
|
34
|
+
alias_method_chain method, :details
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def initialize_with_details(base)
|
39
|
+
@details = Hash.new { |details, attribute| details[attribute] = [] }
|
40
|
+
initialize_without_details(base)
|
41
|
+
end
|
42
|
+
|
43
|
+
def initialize_dup_with_details(other)
|
44
|
+
@details = other.details.deep_dup
|
45
|
+
initialize_dup_without_details(other)
|
46
|
+
end
|
47
|
+
|
48
|
+
def add_with_details(attribute, message = :invalid, options = {})
|
49
|
+
message = message.call if message.respond_to?(:call)
|
50
|
+
error = options.except(*CALLBACKS_OPTIONS).merge(error: message)
|
51
|
+
details[attribute].push(error)
|
52
|
+
add_without_details(attribute, message, options)
|
53
|
+
end
|
54
|
+
|
55
|
+
def clear_with_details
|
56
|
+
details.clear
|
57
|
+
clear_without_details
|
58
|
+
end
|
59
|
+
|
60
|
+
def delete_with_details(attribute)
|
61
|
+
details.delete(attribute)
|
62
|
+
delete_without_details(attribute)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
include Details unless method_defined?(:details)
|
19
66
|
end
|
20
67
|
|
21
68
|
class HashFilter # rubocop:disable Style/Documentation
|
@@ -59,28 +59,6 @@ module ActiveInteraction
|
|
59
59
|
#
|
60
60
|
# @raise (see ActiveInteraction::Runnable::ClassMethods#run!)
|
61
61
|
|
62
|
-
# @!method transaction(enable, options = {})
|
63
|
-
# Configure transactions by enabling or disabling them and setting
|
64
|
-
# their options.
|
65
|
-
#
|
66
|
-
# @example Disable transactions
|
67
|
-
# Class.new(ActiveInteraction::Base) do
|
68
|
-
# transaction false
|
69
|
-
# end
|
70
|
-
#
|
71
|
-
# @example Use different transaction options
|
72
|
-
# Class.new(ActiveInteraction::Base) do
|
73
|
-
# transaction true, isolation: :serializable
|
74
|
-
# end
|
75
|
-
#
|
76
|
-
# @param enable [Boolean] Should transactions be enabled?
|
77
|
-
# @param options [Hash] Options to pass to
|
78
|
-
# `ActiveRecord::Base.transaction`.
|
79
|
-
#
|
80
|
-
# @return [nil]
|
81
|
-
#
|
82
|
-
# @since 1.2.0
|
83
|
-
|
84
62
|
# Get or set the description.
|
85
63
|
#
|
86
64
|
# @example
|
@@ -174,7 +152,13 @@ module ActiveInteraction
|
|
174
152
|
attr_accessor filter.name
|
175
153
|
define_method("#{filter.name}?") { !public_send(filter.name).nil? }
|
176
154
|
|
177
|
-
filter
|
155
|
+
eagerly_evaluate_default(filter)
|
156
|
+
end
|
157
|
+
|
158
|
+
# @param filter [Filter]
|
159
|
+
def eagerly_evaluate_default(filter)
|
160
|
+
default = filter.options[:default]
|
161
|
+
filter.default if default && !default.is_a?(Proc)
|
178
162
|
end
|
179
163
|
end
|
180
164
|
|
@@ -201,8 +185,7 @@ module ActiveInteraction
|
|
201
185
|
#
|
202
186
|
# Runs the business logic associated with the interaction. This method is
|
203
187
|
# only run when there are no validation errors. The return value is
|
204
|
-
# placed into {#result}.
|
205
|
-
# if ActiveRecord is available (see {.transaction}).
|
188
|
+
# placed into {#result}.
|
206
189
|
#
|
207
190
|
# @raise (see ActiveInteraction::Runnable#execute)
|
208
191
|
|
@@ -6,14 +6,12 @@ module ActiveInteraction
|
|
6
6
|
#
|
7
7
|
# @note Must be included after `ActiveModel::Validations`.
|
8
8
|
#
|
9
|
-
# Runs code
|
10
|
-
# validation errors.
|
9
|
+
# Runs code and provides the result.
|
11
10
|
#
|
12
11
|
# @private
|
13
12
|
module Runnable
|
14
13
|
extend ActiveSupport::Concern
|
15
14
|
include ActiveModel::Validations
|
16
|
-
include ActiveInteraction::Transactable
|
17
15
|
|
18
16
|
included do
|
19
17
|
define_callbacks :execute
|
@@ -41,13 +39,8 @@ module ActiveInteraction
|
|
41
39
|
#
|
42
40
|
# @return (see #result)
|
43
41
|
def result=(result)
|
44
|
-
|
45
|
-
|
46
|
-
@_interaction_valid = true
|
47
|
-
else
|
48
|
-
@_interaction_result = nil
|
49
|
-
@_interaction_valid = false
|
50
|
-
end
|
42
|
+
@_interaction_result = result
|
43
|
+
@_interaction_valid = errors.empty?
|
51
44
|
end
|
52
45
|
|
53
46
|
# @return [Boolean]
|
@@ -82,15 +75,12 @@ module ActiveInteraction
|
|
82
75
|
def run
|
83
76
|
return unless valid?
|
84
77
|
|
85
|
-
self.result =
|
78
|
+
self.result =
|
86
79
|
begin
|
87
80
|
run_callbacks(:execute) { execute }
|
88
81
|
rescue Interrupt => interrupt
|
89
82
|
merge_errors_onto_base(interrupt.outcome.errors)
|
90
|
-
|
91
|
-
raise ActiveRecord::Rollback if self.class.transaction?
|
92
83
|
end
|
93
|
-
end
|
94
84
|
end
|
95
85
|
|
96
86
|
def merge_errors_onto_base(new_errors)
|