Reputation: 2942
I want to run a service object in a rake task but need to change a method in a different service that my main service object calls. For example if I have:
main_service.rb
class MainService
def perform
SecondaryService.new.perform
end
end
secondary_service.rb
class SecondaryService
def perform
some_method
end
def some_method
puts 'something'
end
end
And I want to change some_method
to be puts 'anything'
for a one time data fix in a rake task, could I override it by simply redefining the method and is there a way to scope it to just the rake task? I don't want this service to accidentally be called while I run the rake task in case. I was thinking something like this:
one_time.rake
class SecondaryService
def some_method
puts 'anything'
end
end
def one_time_change
MainService.new.perform
end
Upvotes: 1
Views: 375
Reputation: 28305
The code you've suggested should work fine. You could go with that.
However, depending on the context, there is a risk that this strategy may have unintended consequences - i.e. What happens if you accidentally execute the class monkey-patching but expected the original behaviour to be preserved?
A more robust approach is to use dependency injection. By doing this, you can override behaviour with classical inheritance (or even by passing an entirely new object!). For example, something like:
class MainService
def perform(secondary_service: SecondaryService.new)
secondary_service.perform
end
end
class ModifiedSecondaryService < SecondaryService
def some_method
puts 'anything'
end
end
Now, for your one-off rake task, you can run:
PrimaryService.new.perform(secondary_service: ModifiedSecondaryService.new)
Upvotes: 4