Rake tasks踩坑记

最近在工作中编写Rake tasks时碰到了一个以前没有注意的问题,不同命名空间下定义的同名methods出现了覆盖的情况导致bug的产生,自己也是排查很久后才发现重名的问题,所以就把这个记录下来,避免以后再次踩坑。

示例一

# lib/tasks/hello_one.rake

desc "puts hello world one"
task :hello_one do
  hello_world
end

def hello_world
  p "hello tasks one!"
end
复制代码

运行上面的task,结果也是和我们期望的一样

$ rake 'hello_one'

"hello world one"    
复制代码

然后写下另外一个task进行测试

# lib/tasks/hello_two.rake

desc "puts hello world two"
task :hello_two do
  hello_world
end

def hello_world
  p "hello world two"
end
复制代码

运行也得到了期望的结果

$ rake 'hello_two'

"hello world two"
复制代码

但是现在重新运行rake 'hello_one'时却发现输出也变成了hello world two,问题就出来了。当你运行rake任务时,过程是这样的:

  1. rake 'hello_one'
  2. Rails按照文件名称顺序自动加载所有的rake文件
  3. lib/tasks/hello_one.rake文件被加载,定义hello_world方法
  4. lib/tasks/hello_two.rake文件被加载,hello_world方法被重新定义
  5. 运行task代码,最后定义的hello world方法被调用

上述示例可以简单的说明问题,但是一般我们编写时会带有namespace,那现在看看是否会出现上面的情况呢?

示例二

# lib/tasks/hello_one.rake
namespace :one do
  desc "puts hello world one"
  task :hello_one do
    hello_world
  end
  
  def hello_world
    p "hello tasks one!"
  end
end

# lib/tasks/hello_two.rake
namespace :two do
  desc "puts hello world two"
  task :hello_two do
    hello_world
  end

  def hello_world
    p "hello world two"
  end
end
复制代码

运行上述代码,结果如下:

$ rake 'one:hello_one'
"hello world two"

$ rake 'two:hello_two'
"hello world two"
复制代码

从运行结果可以看出来,namespace对于方法定义没有影响,方法依旧是全局性质的,问题依旧存在。

对于这个一般有几个常用的解决办法:

  1. 确保每一个定义的方法名称唯一(最直接也最简单,但是后续容易重名踩坑)
  2. 把方法的逻辑写回到task中去,不单独定义相关的method(当然这是相反的操作,如果方法简单那是可以这么操作的)
  3. 将方法逻辑抽离,单独封装成Class或者是Module,然后在task中调用即可(当然若与model相关,可以写成对应的实例方法或者类方法,这都是可以的)

第三个相对是一个较好的解决方案,但是呢具体的使用还是需要根据当时的业务场景及代码复杂度等因素去选择判断,解决问题的方案才是好方案。

结语

最后,文章发布于个人博客,地址: blog.renyijiu.com,欢迎关注,不定时更新。

转载于:https://juejin.im/post/5b7eae866fb9a019cb3cd710

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值