一篇看到的讲解得不错的文章 http://blog.csdn.net/clskkk2222/article/details/6735365

这里还有一些例子:

Rake Documentation 
Rails Rake Tutorial 
Using the Rake Building Language

===========================================================================================================

这是Rails Envy网站的一篇Rake指南,你可以在这里找到原文。

作为RoR开发者,你对Rake一定不会陌生,你可能用它来完成你的单元测试,也可能是迁移数据库,但是你真正理解这些Rake任务到底是怎么运作的吗?你有尝试过创建你自己的Rake任务吗?

在这篇文章中,我们将会介绍Rake的由来,以及如何在Rails中使用它,通过这篇文章的学习,你将掌握如何使用Rake创建你自己的任务。

为什么要有Rake

要理解Rake,我们首先得来了解一下Rake的历史悠远的祖先:Make。因此我们需要暂且回到解释型语言产生之前的久远年代,在那个时代,所有代码都需 要被编译,然后才能够被执行,所以当你从Internet下载到一个相当庞大的程序后,一般来说,除了源代码,程序包中还会包含一个类似 “install_me.sh”的Shell脚本,它会负责帮你完成源代码的编译,并生成最终的可执行文件。

这看起来很完美,不是吗?对用户来说可能如此,但对于开发者来说,这却是个相当粗笨的方法,因为即使你只是修改了一个文件中的一小段代码,”install_me.sh”也必须将所有的源代码都重新编译一遍,才能生成最终的可执行文件。

因此,针对这个问题,Bell实验室的Stuart Feldman创造了Make:

  • Make可以识别自上次编译之后那些文件发生了改变,从而在下次编译时只对这些发生改变的文件进行编译,而忽略那些没有变化的文件,从而大大降低了程序的编译时间。
  • Make同时支持依赖关系追踪,也就是你可以告诉编译器,文件A依赖于文件B,因此当文件B发生改变后,文件A也会被重新编译,并且如果编译文件A时,文件B还没有被编译,那么Make会告诉编译器应该先编译文件B。

Make 实际上是一个跟ls和dir差不多的可执行文件,只不过你需要提供一个Makefile文件给它作为输入,Makefile中对每个需要编译的文件及它们 的依赖关系进行定义,Makefile的语法类似于Shell脚本,但又有些不同,这里我们不需要关心Makefile的语法。

随着Make的语言中立性,任何语言的程序都可以使用它来作为构建(build)系统,事实上,在Rake产生之前,许多Ruby项目也是采用Make作为构建系统的。

你可能会奇怪:“Ruby程序并不需要被编译,为何还要使用Make呢?”,是的,Ruby的确不需要编译,事实上,Ruby程序员使用Make是出于以下两个原因:

  • 创 建任务,对于大型程序来说,编译完成并不意味着可以了事,往往你需要编写一大堆的脚本来控制它的运行,或者查看它的运行状态等等,这种情况下,你就可以创 建一个Makefile来管理所有这些任务,然后你就可以使用诸如“make stupid”,“make clever”来分别运行糊涂和聪明任务了。
  • 依 赖关系追踪,当你开始写一个库的时候,你可能会发现,越来越的的任务存在重复,比如”migrate“和”shema: dump“就都需要连接数据库,这时你就可以抽象出一个”connect_to_db”任务,并设置”migrate”和”shema: dump”任务都依赖于”connect_to_db”,这样当你单独运行”migrate”或者”shema:dump”任务时, “connect_to_db”任务都会被首先调用,如果你同时运行这两个任务,那么”connect_to_db”任务只会被执行一次。

Rake是怎么来的?

很多年以前,当 Jim Weirich还在为一个Java项目工作时,他最初的选择也是Makefile,但是很快他意识到:要是能够在Makefile中嵌入Ruby代码,那会是多么的方便呀,于是,Rake就这么产生了。

Rake支持任务创建,任务依赖关系追踪,以及文件编译时间识别。最后一个功能对Ruby程序员应该用不到,但如果你同时还是一个C程序员,那么你可以尝试使用Rake来替代Make。

Rake如何工作

让我们通过一个例子来说明吧,假设我今天很郁闷,想要借酒消愁,这个过程涉及以下几个任务:

  1. 买酒
  2. 买下酒菜
  3. 搞掂它们

假设使用Rake来管理这3个任务,那么我首先需要创建一个Rakefile文件:

task :purchaseAlcohol do
  puts "来瓶五粮液"
end
task :mixDrink do
  puts "上盘花生米"
end
task :getSmashed do
  puts "老板, 啥时学的分身术, 很强嘛?"
end

然后我就可以从Rakefile文件所在的目录来完成这些任务了:


$ rake purchaseAlcohol
来瓶五粮液
$ rake mixDrink
上盘花生米
$ rake getSmashed
老板, 啥时学的分身术, 很强嘛?

很简单吧!但是有些问题,我可不想还没喝酒吃东西就看到老板的分身,这会被人当作精神不正常。

如何组织任务的依赖关系

很简单:

task :purchaseAlcohol do
  puts "来瓶五粮液"
end
task :mixDrink => :purchaseAlcohol do
  puts "上盘花生米"
end
task :getSmashed => :mixDrink do
  puts "老板, 啥时学的分身术, 很强嘛?"
end

搞掂,现在再试试:

$ rake purchaseAlcohol
来瓶五粮液
$ rake mixDrink
来瓶五粮液
上盘花生米
$ rake getSmashed
来瓶五粮液
上盘花生米
老板, 啥时学的分身术, 很强嘛?

就像你看到的,现在我想要醉必须得先喝点酒吃点花生才行,不过一个人喝酒总归有些无聊,所以我想喊些哥们一起来喝,但是我又懒得跟他们解释为啥突然喊他们来喝酒(本人平时比较吝啬),我想到一个偷懒的办法,给他们看文档,但是究竟该怎么为我的Rake任务生成文档呢?

为Rake任务生成文档
再简单不过了:

desc "工作郁闷,想喝点酒"
task :purchaseAlcohol do
  puts "来瓶五粮液"
end
desc "得有点下酒菜"
task :mixDrink => :purchaseAlcohol do
  puts "来盘花生米"
end
desc "开喝,不醉不归"
task :getSmashed => :mixDrink do
  puts "老板, 啥时学的分身术, 很强嘛?"
end

就像你看到的,我的每个任务都有了一个desc字段,现在我和我的朋友们就可以通过rake -T或者rake –task来查看每个任务的文档了:

$ rake --tasks
rake getSmashed # 开喝,不醉不归
rake mixDrink # 得有点下酒菜
rake purchaseAlcohol # 工作郁闷,想喝点酒

Rake命名空间

一旦养成了工作郁闷就喝酒的好习惯之后,你很快就会发现,自己成了个酒鬼,因此你不得不写一大堆Rake任务来集结你的狐朋狗友们,这时你就会发现命名空间的重要性:

namespace :alcoholic do
  desc "工作郁闷,想喝点酒"
  task :purchaseAlcohol do
    puts "来瓶五粮液"
  end
  desc "得有点下酒菜"
  task :mixDrink => :purchaseAlcohol do
    puts "来盘花生米"
  end
  desc "开喝,不醉不归"
  task :getSmashed => :mixDrink do
    puts "老板, 啥时学的分身术, 很强嘛?"
  end
end
namespace :girlfriend do
  desc "那个,喝点红酒吧"
  task :purchaseAlcohol do
    puts "来瓶干红"
  end
end

命名空间允许你将你的任务进行分类,你可以在一个Rakefile内创建多个命名空间,现在输入rake –tasks你会得到如下输出:

rake alcoholic:getSmashed # 开喝,不醉不归
rake alcoholic:mixDrink # 得有点下酒菜
rake alcoholic:purchaseAlcohol # 工作郁闷,想喝点酒
rake girlfriend:purchaseAlcohol # 那个,喝点红酒吧

有用的任务

上面都是扯淡,毕竟人生除了喝酒还有更重要的事情等着我们去做,下面,我们来干点正经事,假设我们需要完成这样一个任务,给定一组目录,如果不存在,就创建它们,我创建的Rake任务如下:

desc "Create blank directories if they don't already exist"
task(:create_directories) do
  # The folders I need to create
  shared_folders = ["icons","images","groups"]
    for folder in shared_folders
    # Check to see if it exists
    if File.exists?(folder)
      puts "#{folder} exists"
    else
      puts "#{folder} doesn't exist so we're creating"
      Dir.mkdir "#{folder}"
    end
  end
end

默认情况下,Rake具有所有File Utils包的功能,当然你也可以通过引用其他库来做任何你想做的事情,那么下一个问题就是:我应该如何在Rails中使用Rake呢?

在Rails中使用Rake

每个Rails应用本身都在带有许多预定义的Rake任务,你可以通过在你的Rails应用的根目录下执行rake –tasks来查看可用的rake任务,别以后了,现在就试试吧,我等你!

要创建新的Rake任务,你只需打开你的Rails应用的lib/tasks目录,并将你的Rakefile命名为”somethins.rake”即可,它会自动被主Rakefile引用,然后你就可以在主目录下调用你的rake任务了,让我们继续上面那个例子:

utils.rake

namespace :utils do
  desc "Create blank directories if they don't already exist"
 task(:create_directories) do
  # The folders I need to create
  shared_folders = ["icons","images","groups"]
  for folder in shared_folders
   # Check to see if it exists
   if File.exists?("#{RAILS_ROOT}/public/#{folder}")
    puts "#{RAILS_ROOT}/public/#{folder} exists"
   else
    puts "#{RAILS_ROOT}/public/#{folder} doesn't exist so we're creating"
    Dir.mkdir "#{RAILS_ROOT}/public/#{folder}"
   end
  end
 end
end

再次执行rake –tasks,你会看到如下结果

......
rake tmp:pids:clear # Clears all files in tmp/pids
rake tmp:sessions:clear # Clears all files in tmp/sessions
rake tmp:sockets:clear # Clears all files in tmp/sockets
rake utils:create_directories # Create blank directories if they
don't already exist

从Rake任务中可以访问rails model吗?

是的,当然可以,这是我使用Rake最主要的用途:运行一些需要手动执行的任务,或者是需要脱离Rails定期运行的任务,下面是一个简单的例子:

namespace :utils do
  desc "Finds soon to expire subscriptions and emails users"
  task(:send_expire_soon_emails => :environment) do
    # Find users to email
    for user in User.members_soon_to_expire
      puts "Emailing #{user.name}"
      UserNotifier.deliver_expire_soon_notification(user)
    end
  end
end

实在是很简单,你只需要在你的任务之前执行”=> :environment“就可以了。

如果需要在开发模式执行这个任务,直接敲”rake utils:send_expire_soon_emails”就可以了,如果是产品模式,敲”rake RAILS_ENV=production utils:send_expire_soon_emails”,现在如果我想让这个任务每天晚上运行一次,那么,我只需要在cronjob文件中加入下面这行就可以了:

0 0 * * * cd /var/www/apps/rails_app/ && /usr/local/bin/rake RAILS_ENV=production utils:send_expire_soon_emails

还有更多的例子吗?

不用担心,只要你有时间,并且愿意看,例子大把:

rails rake和示例的更多相关文章

  1. rails rake 版本问题

    rails rake 版本问题 通常情况下,如果我们电脑上同时装了不同版本的rake时,运行rake命令时会出错,如: rake db:migrate rake aborted! You have a ...

  2. rails常用命令示例

    数据迁移命令 1.一下命令执行后会在db\migrate下产生同名数据迁移文件(文件内容可自行修改,基本语法见“数据迁移文件”部分) 创建model:rails generate model user ...

  3. rails学习笔记: rake db 相关命令

    rails学习笔记: rake db 命令行 rake db:*****script/generate model task name:string priority:integer script/g ...

  4. [转]2010 Ruby on Rails 書單 與 練習作業

    原帖:http://wp.xdite.net/?p=1754 ========= 學習 Ruby on Rails 最快的途徑無非是直接使用 Rails 撰寫產品.而這個過程中若有 mentor 指導 ...

  5. rake

    ruby-rake https://rubygems.org/gems/rake 官方文档 https://ruby.github.io/rake/ http://docs.seattlerb.org ...

  6. crawler_爬虫_反爬虫策略

    关于反爬虫和恶意攻击的一些策略和思路   有时网站经常受到恶意spider攻击,疯狂抓取网站内容,对网站性能有较大影响. 下面我说说一些反恶意spider和spam的策略和思路. 1. 通过日志分析来 ...

  7. redmine on centos

    一 前言 前前后后搭建redmine,花费了很多时间.期间会遇到各种坑,因此总结下自己的方法,分享给各位童鞋. 二 操作系统  centos release 6.9 详细信息如下图:   三 安装步骤 ...

  8. migrate

    数据类型 引用 # :string, :text, :integer, :float,:decimal, :datetime, :timestamp, :time, :date, # :binary, ...

  9. GitLab CI/CD的官译【原】

    CI / CD方法简介 软件开发的持续集成基于自动执行脚本,以最大限度地减少在开发应用程序时引入错误的可能性.从新代码的开发到部署,它们需要较少的人为干预甚至根本不需要干预. 它涉及在每次小迭代中不断 ...

随机推荐

  1. jdbc与odbc的差别,感悟,学习。。。

    什么是JDBC? JDBC, 全称为Java DataBase Connectivity standard, 它是一个面向对象的应用程序接口(API), 通过它可訪问各类关系数据库.JDBC也是jav ...

  2. HDFS--Hadoop分布式文件系统

    HDFS是什么 HDFS设计特性和概念 HDFS,全称是Hadoop Distributed Filesystem,是一个分布式的文件系统,以流式数据訪问模式来存储超大文件(一次写入.多次读取). H ...

  3. MPU6050读取FIFI数据时mpu_dmp_get_data的返回值一直是1

    试验中发现:不断进行循环读fiffo就可以得到正常数据.形如这样 );//返回值:0,DMP成功解出欧拉角 printf("pitch=%f\troll=%f\tyaw=%f\r\n&quo ...

  4. django中models阅读笔记

    一.使用数据库需要设置settings.py文件. DATABASES = { 'default': { 'ENGINE': 'django.db.backends.', # Add 'postgre ...

  5. 分享八:特殊的mysql函数

    一:MYSQL自定义排序函数FIELD() MySQL可以通过field()函数自定义排序,格式:field(value,str1,str2,str3,str4),value与str1.str2.st ...

  6. PHP位操作符

    二进制怎么算 http://www.doc88.com/p-474114598610.html 这个涉及到系统底层,WEB开发中几乎没用到,知道下有这个东西就好了.底层的东西解释总是简单不了的. 变量 ...

  7. Spring在xml配置里配置事务

    事先准备:配置数据源对象用<bean>实例化各个业务对象. 1.配置事务管理器. <bean id="transactionManager" class=&quo ...

  8. VC++学习之多线程(2)

    创建一个线程,自然有一个对应的系统API来完毕.CreateThread这个函数就用来创建线程的. 各种參数的用途我就不多说了,这里直接贴一个我自己练习的样例 1.以下是一个创建一个线程的样例,当然, ...

  9. 批处理学习笔记1 - Hellow World

    记录自己学习批处理的一点总结吧. 批处理的好处: 可以配合vs,在build完文件之后执行自己的批处理命令. 可以批量修改文件名,或者进行复杂的查询等,对文件可编程操作. 从Hellow world开 ...

  10. 网站的PV UV IP---网站常见软件性能

    IP,衡量不同时间段的上网人数.00:00-24:00内相同的地址被计算一次.例:日300W IP,至少300W人访问PV,衡量页面受欢迎程度.每刷新一次,被记录一次(刷pv),网站被访问的页面的数量 ...