2727#++
2828
2929module BaseServices
30- class Copy < ::BaseServices ::BaseContracted
30+ class Copy < ::BaseServices ::Write
3131 alias_attribute ( :source , :model )
3232
3333 ##
@@ -39,7 +39,9 @@ def self.copy_dependencies
3939 ##
4040 # collect copyable associated modules
4141 def self . copyable_dependencies
42- copy_dependencies . map do |service_cls |
42+ copy_dependencies
43+ . flat_map { |dependency | [ dependency ] + dependency . copy_dependencies }
44+ . map do |service_cls |
4345 {
4446 identifier : service_cls . identifier ,
4547 name_source : -> { service_cls . human_name } ,
@@ -61,33 +63,30 @@ def initialize(user:, source: nil, model: nil, contract_class: nil, contract_opt
6163 end
6264
6365 def call ( params )
64- User . execute_as ( user ) do
65- prepare ( params )
66- perform ( params )
67- end
68- end
66+ prepare_state ( params )
6967
70- def after_validate ( params , _call )
71- # Initialize the target resource to copy into
72- call = initialize_copy ( source , params )
68+ super
69+ end
7370
71+ def persist ( call )
7472 # Return only the unsaved copy
7573 return call if params [ :attributes_only ]
7674
77- # Try to save the result or return its errors
78- copy_instance = call . result
79- unless copy_instance . save
80- return ServiceResult . failure ( result : copy_instance , errors : copy_instance . errors )
81- end
82-
83- self . class . copy_dependencies . each do |service_cls |
84- next if skip_dependency? ( params , service_cls )
75+ super . tap do |super_call |
76+ copy_instance = super_call . result
77+ self . class . copy_dependencies . each do |service_cls |
78+ next if skip_dependency? ( params , service_cls )
8579
86- call . merge! call_dependent_service ( service_cls , target : copy_instance , params :) ,
87- without_success : true
80+ super_call . merge! call_dependent_service ( service_cls , target : copy_instance , params :) ,
81+ without_success : true
82+ end
8883 end
84+ end
85+
86+ def after_perform ( call )
87+ return call if params [ :attributes_only ]
8988
90- call
89+ super
9190 end
9291
9392 protected
@@ -110,7 +109,7 @@ def skip_dependency?(_params, _dependency_cls)
110109 #
111110 # Note that for dependent copy services to be called
112111 # this will already be present.
113- def prepare ( _params )
112+ def prepare_state ( _params )
114113 # Retain the source project itself
115114 state . source = source
116115 end
@@ -124,8 +123,8 @@ def call_dependent_service(service_cls, target:, params:)
124123 . call ( params :)
125124 end
126125
127- def initialize_copy ( source , params )
128- raise NotImplementedError
126+ def instance ( _params )
127+ source . class . new
129128 end
130129
131130 def default_contract_class
0 commit comments