@@ -107,6 +107,85 @@ def include_errors!(model, **mapping)
107107 halt_if_errors!
108108 end
109109 end
110+
111+ concern :AllRunner do
112+ class AllExecution
113+ attr_reader :klass , :params
114+
115+ def initialize ( klass :, params :)
116+ @klass = klass
117+ @params = params
118+ end
119+
120+ def run ( opts = { } )
121+ execute ( opts ) { klass . run ( _1 ) }
122+ end
123+
124+ def run! ( opts = { } )
125+ execute ( opts ) { klass . run! ( _1 ) }
126+ end
127+
128+ def delay ( **delay_opts )
129+ DelayedExecution . new ( klass :, params :, delay_opts :)
130+ end
131+
132+ private
133+
134+ def noop
135+ yield
136+ end
137+
138+ def default_params
139+ object_filters = klass . filters
140+ . reject { _2 . default? }
141+ . select { _2 . is_a? ( ActiveInteraction ::ObjectFilter ) }
142+ raise "only one object input allowed" if object_filters . size > 1
143+ name , _ = object_filters . first
144+
145+ {
146+ name => name . to_s . classify . constantize . all ,
147+ }
148+ end
149+
150+ def execute ( opts , around : method ( :noop ) )
151+ params = self . params . dup . reverse_merge ( default_params )
152+
153+ name , scope = params . find { _2 . is_a? ( ActiveRecord ::Relation ) }
154+ params . delete ( name )
155+
156+ scope . find_in_batches do |batch |
157+ around . call do
158+ batch . each do |record |
159+ yield ( opts . merge ( name => record , **params ) )
160+ end
161+ end
162+ end
163+ end
164+ end
165+
166+ class DelayedExecution < AllExecution
167+ attr_reader :delay_opts
168+ def initialize ( delay_opts : { } , **kw )
169+ super ( **kw )
170+ @delay_opts = delay_opts
171+ end
172+
173+ def run ( opts = { } )
174+ around = GoodJob ::Bulk . method ( :enqueue )
175+ execute ( opts , around :) { klass . delay ( delay_opts ) . run ( _1 ) }
176+ end
177+
178+ def run! ( opts = { } )
179+ run ( opts )
180+ end
181+ end
182+
183+ class_methods do
184+ def all ( params = { } )
185+ AllExecution . new ( klass : self , params :)
186+ end
187+ end
188+ end
110189 end
111190end
112191
0 commit comments