原文链接:http://hi.baidu.com/%D0%C7203/blog/item/ebda2dd09f1d698ea1ec9c7a.html
原文:Ruby on Rails Rake Tutorial (aka. How rake turned me into an alcoholic)
引言:作为一个rails的开发者,你可能很熟悉使用rake进行你的测试,或者使用rake db:migrate运行你的migrations,但是你真的知道Rake的背后故事吗?你意识到可以自己写一个Rake任务或者一个有用的lib吗?
下面是我们使用Rake任务的例子:
1、给列表中的用户发送邮件
2、每晚数据的计算和报告
3、过期或重新生成缓存
4、备份数据和svn版本(how's this : subversion repository)
5、运行数据处理脚本(sort of,how much is called this )
6、Pouring drinks to get a good buzz on(一句玩笑,是这两位仁兄的风格)
task :purchaseAlcohol do puts "Purchased Vodka" end task :mixDrink do puts "Mixed Fuzzy Navel" end task :getSmashed do puts "Dood, everthing's blurry, can I halff noth'r drinnnk?" end这样我可以在这个Rakefile的目录,分别运行这些任务:
$ rake purchaseAlcohol Purchased Vodka $ rake mixDrink Mixed Fuzzy Navel $ rake getSmashed Dood, everthing's blurry, can I halff noth'r drinnnk?酷!但是从顺序上看,我可以用任何的顺序运行这个任务。比如喝醉在买酒或者喝酒之前。当然这不符合人的习惯。
task :purchaseAlcohol do puts "Purchased Vodka" end task :mixDrink => :purchaseAlcohol do puts "Mixed Fuzzy Navel" end task :getSmashed => :mixDrink do puts "Dood, everthing's blurry, can I halff noth'r drinnnk?" end这样,如果想喝酒,就得先去买,如果想喝醉,就得先喝酒。
$ rake purchaseAlcohol Purchased Vodka $ rake mixDrink Purchased Vodka Mixed Fuzzy Navel $ rake getSmashed Purchased Vodka Mixed Fuzzy Navel Dood, everthing's blurry, can I halff noth'r drinnnk?看到了吧,我喝醉和,因为酒已经买了,也被我喝了。(译者:我是喜欢百事的,所以倘若我写,定然拿百事当例子。但是我让我儿子和可口,为什么呢?下面告诉你。)
desc "This task will purchase your Vodka" task :purchaseAlcohol do puts "Purchased Vodka" end desc "This task will mix a good cocktail" task :mixDrink => :purchaseAlcohol do puts "Mixed Fuzzy Navel" end desc "This task will drink one too many" task :getSmashed => :mixDrink do puts "Dood, everthing's blurry, can I halff noth'r drinnnk?" end看到了吧,我的每个任务都添加了desc,这样我们可以输入"rake -T"或者"rake --tasks":
$rake --tasks rake getSmashed # This task will drink one too many rake mixDrink # This task will mix a good cocktail rake purchaseAlcohol # This task will purchase your Vodka简单乎?呵呵
namespace :alcoholic do desc "This task will purchase your Vodka" task :purchaseAlcohol do puts "Purchased Vodka" end desc "This task will mix a good cocktail" task :mixDrink => :purchaseAlcohol do puts "Mixed Fuzzy Navel" end desc "This task will drink one too many" task :getSmashed => :mixDrink do puts "Dood, everthing's blurry, can I halff noth'r drinnnk?" end end命名空间允许你将一些任务放到特定的分类中,在一个Rakefile中,你可以加入几个命名空间。运行rake --tasks
rake alcoholic:getSmashed # This task will drink one too many rake alcoholic:mixDrink # This task will mix a good cocktail rake alcoholic:purchaseAlcohol # This task will purchase your Vodka所以如果想运行这个任务,只要输入 rake alcoholic:getSmashed:
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,或者加入其他的部分。
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注意上面的代码,我使用了#{RAILS_ROOT} 来得到rails应用的当前位置,现在运行“rake --tasks”,你可以看到我们的任务已经添加到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 ...
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使用你的model只用一步,"=> :environment"
0 0 * * * cd /var/www/apps/rails_app/ && /usr/local/bin/rake RAILS_ENV=production utils:send_expire_soon_emails相当的方便。
# This is needed because the existing version of directory in Rake is slightly broken, but Jim says it'll be fixed in the next version. alias :original_directory :directory def directory(dir) original_directory dir Rake::Task[dir] end # Do the directory creation namespace :utils do task :create_directories => [ directory('public/icons'), directory('public/images'), directory('public/groups'), ] end