首页 > 解决方案 > 如何为一次性 rake 任务覆盖 ruby​​ 中的方法?

问题描述

我想在 rake 任务中运行服务对象,但需要更改我的主要服务对象调用的不同服务中的方法。例如,如果我有:

main_service.rb

class MainService
  def perform
    SecondaryService.new.perform
  end
end

辅助服务.rb

class SecondaryService
  def perform
    some_method
  end

  def some_method
    puts 'something'
  end
end

而且我想更改some_methodputs 'anything'rake 任务中的一次性数据修复,我可以通过简单地重新定义方法来覆盖它吗?有没有办法将其范围限定为 rake 任务?我不希望在运行 rake 任务时意外调用此服务,以防万一。我在想这样的事情:

one_time.rake

class SecondaryService
  def some_method
    puts 'anything'
  end
end

def one_time_change
  MainService.new.perform
end

标签: rubyrake

解决方案


您建议的代码应该可以正常工作。你可以这样做。

但是,根据上下文,这种策略可能会产生意想不到的后果——即,如果您不小心执行了猴子修补类但希望保留原始行为会发生什么?

一种更健壮的方法是使用依赖注入。通过这样做,您可以使用经典继承覆盖行为(甚至通过传递一个全新的对象!)。例如,类似:

class MainService
  def perform(secondary_service: SecondaryService.new)
    secondary_service.perform
  end
end

class ModifiedSecondaryService < SecondaryService
  def some_method
    puts 'anything'
  end
end

现在,对于一次性 rake 任务,您可以运行:

PrimaryService.new.perform(secondary_service: ModifiedSecondaryService.new)

推荐阅读