rake详解(使用篇)

作者:周星 发布:2017-10-07

      Rake 是 Rails 的一个非常有用的工具,你可以把它理解为 ruby 的 make,本次分享将和您一起学习如何写我们自己的 Rake 任务。

首先,我们需要一个 Rakefile 文件,来看一下 Rails4 的 Rakefile

# Add your own tasks in files placed in lib/tasks ending in .rake,
# for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.

require File.expand_path('../config/application', __FILE__)
Rails.application.load_tasks

我们看到它加载了 Rails 环境,并且执行了 load_tasks 方法,由于 load_tasks 方法及源码等内容对新人微深入,我们会在后续的分享中来探索 Rails Rake 任务的执行机制等。

拥有了 Rakefile 文件后,我们需要创建 .rake 文件,并在里面 code 我们的任务,Rails 项目在 lib 目录为我们生成了 tasks 文件夹,我们在里面新建一个 learn_rake.rake

vi lib/tasks/learn_rake.rake

今天是情人节(valentine's day),那我们就以此为例好了

task :valentines_day do
  puts "Let's celebrate valentine's day"
end

然后在项目目录中执行:bundle exec rake valentines_day

是不是看到了我们 puts 的信息,好吧,这太简单了,那我们新增一个需求,过情人节需要什么?code?NO NO,需要一个 lover,下面我们修改一下 learn_rake.rake 里面的程序:

task :generate_lover do
  puts "You got a lover now"
end

task :valentines_day => :generate_lover do
  puts "Let's celebrate valentine's day"
end

再执行一下:bundle exec rake valentines_day,我们看到了两条打印信息:

depot ➤ bundle exec rake valentines_day
You got a lover now
Let's celebrate valentine's day

注意一下我们修改的 valentines_day 任务,这里“键” :valentines_day 对应了一个“值” :generate_lover,说明 valentines_day 任务的执行需要依赖 generate_lover 任务,那么我们再加一个需求呢?想要 celebrate valentine's day 不但需要 generate_lover,还需要 today_is_feb_14 ,那这个任务应该怎么写呢?答案是再写一个 today_is_feb_14 任务,然后把 :valentines_day 的值改为一个数组,你来完成这一部分代码吧

注:数组中的顺序决定依赖任务执行的顺序

既然是 Rake 任务是在 Rails 程序中的,那它一定能处理 Rails 任务了,我们来写一个示例代码,打印数据库中第一个学生的名字:

task :first_student do
  puts Student.first.name
end

执行这个任务,它并没有按我们的想法来工作,而是报了错 uninitialized constant Student,原因是我们并没有指定这个任务依赖 Rails 环境

task :first_student => :environment 
  puts Student.first.name
end

:environment 表示执行 rake 任务时的 Rails 环境参数,默认为 development 环境,你可以通过 RAILS_ENV 参数来修改它: bundle exec rake first_student RAILS_ENV=production

很多时候我们的 Rake 任务需要在执行时传入参数,这是一个非常有用的用法,请看下面这个示例:


task :my_lover_is, [:name] do |t, args|
  puts "my lover is #{args.name}"
end

执行命令:

depot ➤ bundle exec rake 'my_lover_is[you]'
my lover is you

注意要在任务名两边加单引号

下面介绍两个让我们的 Rake 任务变得 perfect 的方法,首先是 desc 方法:

desc "show who is my lover"
task :my_lover_is, [:name] do |t, args|
  puts "my lover is #{args.name}"
end

desc 后面的参数必须为字符串,它的作用类似于注释,当我们执行 rake -T 的时候,会展示给我们这个 Rake 任务对应的描述

depot ➤ bundle exec rake -T | grep "my lover"
rake my_lover_is[name]                  # show who is my lover

其次是 namespace 方法,namespace 方法可以把我们的 Rake 任务分组,这样可以避免一些命名冲突等,也可以让我们的 Rake 任务组织得更有条理一些,请看本次分享最后的示例程序:

namespace :celebrate_task do
  task :generate_lover do
    puts "You got a lover now"
  end

  task :today_is_feb_14 do
    puts "It's valentine's day"
  end

  task :valentines_day => [:today_is_feb_14, :generate_lover] do
    puts "Let's celebrate valentine's day"
  end

  desc "show who is my lover"
  task :my_lover_is, [:name] do |t, args|
    puts "my lover is #{args.name}"
  end
end

namespace :rails_tasks do
  task :first_student => :environment do
    puts Student.first.name
  end
end

执行命令为:bundle exec rake namespace:task

总结一下本次分享的内容:

  • Rake 任务的写法
  • Rake 任务依赖其它
  • Rake 任务如何传入参数
  • Rake 任务的 desc 和 namespace

下次分享我们将深入探索 Rake,如果您对本次分享有什么意见或建议,请联系博主。

支付宝扫码赞助博主


评论(0)