rails rake和樣本

來源:互聯網
上載者:User

標籤:des   blog   http   io   os   使用   java   ar   strong   

一篇看到的講解得不錯的文章 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

還有更多的例子嗎?

不用擔心,只要你有時間,並且願意看,例子大把:

    • These brand new rake tasks in Edge Rails create and reset your databases for you. Neato!
    • Craig Ambrose wrote a Rake task to do database backups, which you can use.
    • Adam Greene put together a set of Rake tasks that allow you to backup all your data to Amazon S3
    • Jay Fields made a good point when he talked about testing rake tasks
    • Err the blog talks about a new way of setting the RAILS_ENV and teaches how to use rake to boot you into a Mysql shell (be sure to read the comments if you browse this one).
    • Last, but not least, there’s the Rake Bookshelf Books and Martin Fowler’s Using the Rake Build Language tutorial . Both of these are pretty thorough, but also a little dated

rails rake和樣本

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.