亚洲免费在线-亚洲免费在线播放-亚洲免费在线观看-亚洲免费在线观看视频-亚洲免费在线看-亚洲免费在线视频

Ruby on Rails中的Rake教程

系統(tǒng) 1944 0

原文: Ruby on Rails Rake Tutorial (aka. How rake turned me into an alcoholic)
引言:作為一個(gè)rails的開發(fā)者,你可能很熟悉使用rake進(jìn)行你的測(cè)試,或者使用rake db:migrate運(yùn)行你的migrations,但是你真的知道Rake的背后故事嗎? 你意識(shí)到可以自己寫一個(gè)Rake任務(wù)或者一個(gè)有用的lib嗎

下面是我們使用Rake任務(wù)的例子:

1、給列表中的用戶發(fā)送郵件
2、每晚數(shù)據(jù)的計(jì)算和報(bào)告
3、過期或重新生成緩存
4、備份數(shù)據(jù)和svn版本( how's this : subversion repository )
5、運(yùn)行數(shù)據(jù)處理腳本(sort of,how much is called this )
6、Pouring drinks to get a good buzz on(一句玩笑,是這兩位仁兄的風(fēng)格)

這篇文章中,我們將討論為什么要?jiǎng)?chuàng)建Rake,和他怎么樣幫助我們的rails應(yīng)用。最好你可以寫自己的Rake。

一、歷史回顧:make

為了了解Rake的來歷,我們先了解一下Rake的爺爺:Make。
讓我們回到那個(gè)代碼塊需要編譯,解釋性語言和iphone還沒出現(xiàn)在地球上的時(shí)代。

回到那時(shí),我們下載的大型程序,還是一堆源代碼和一個(gè)shell腳本。這個(gè)shell腳本包含了所有需要用來compile/link/build的代碼。你需要運(yùn)行“install_me.sh”這個(gè)腳本,每一行代碼將被運(yùn)行(編譯每一行源文件),然后生成一個(gè)你能夠運(yùn)行的文件。

對(duì)于大多數(shù)人這樣是不錯(cuò)的,但是對(duì)于程序開發(fā)人員卻是一個(gè)不幸。每次你對(duì)源代碼進(jìn)行一個(gè)小的改動(dòng),并進(jìn)行測(cè)試的時(shí)候,你需要回到shell腳本,并重新編譯所有的源代碼,顯然對(duì)于大的程序“那是相當(dāng)?shù)摹焙臅r(shí)的。

1977年(作者出生那年,我78年),貝爾實(shí)驗(yàn)室的Stuart Feldman創(chuàng)造了“make”。解決了編譯時(shí)間過長(zhǎng)的問題。Make用來編譯程序,取得兩方面的進(jìn)步:

Stuart Feldman

(1)Make可以發(fā)現(xiàn)哪個(gè)文件在上一次編譯后改動(dòng)過,根據(jù)這點(diǎn),再次運(yùn)行Make時(shí),僅編譯改動(dòng)過的文件。這個(gè)很大程序上減少了重新編譯大型程序的時(shí)間。

(2)Make可以進(jìn)行從屬跟蹤。你可以告訴編譯器,源文件A的編譯需要源文件B,源文件B的編譯需要源文件C,所以Make在編譯A時(shí)發(fā)現(xiàn)B沒有編譯,將會(huì)先編譯B。

可以這樣定義:Make是一個(gè)可執(zhí)行程序。像ls或dir一樣。讓Make理解如何讓編譯一個(gè)項(xiàng)目,需要?jiǎng)?chuàng)建一個(gè)makefile文件,描述所有的源文件和依賴關(guān)系。makefiles有自己的語法,你不用去了解。

這些年Make出現(xiàn)了其他的變體,并且被其他的語言使用。事實(shí)上,ruby用戶在rake出現(xiàn)前也在使用它。

“但是,ruby并不需要編譯,我們用它來干嘛?”

是啊。ruby是一個(gè)解釋性語言,我們不需要編譯它的源代碼,所以ruby程序員為什么使用它呢?

兩個(gè)重要的原因:

(1)創(chuàng)建任務(wù)
在大型的應(yīng)用中,你經(jīng)常編寫腳本,在命令行下運(yùn)行一些任務(wù)。比如清除緩存,維護(hù)任務(wù),或者遷移數(shù)據(jù)庫。你可以寫一個(gè)MakeFile來組織你的任務(wù),而不是寫十個(gè)不相干的腳本(或者一個(gè)復(fù)雜的)。這樣你可以簡(jiǎn)單的運(yùn)行:“make stupid”。

(2)從屬任務(wù)跟蹤
當(dāng)你開始寫一些維護(hù)任務(wù)的時(shí)候,可能發(fā)現(xiàn)有些任務(wù)的使用可能有重復(fù)。比如,“migrate”任務(wù)和“schema:dump”都需要鏈接數(shù)據(jù)庫,這樣我可以創(chuàng)建一個(gè)任務(wù)"connect_to_database",使“migrate”和“schema:dump”都依賴于"connect_to_database",這樣下次運(yùn)行“migrate”時(shí),"connect_to_database"會(huì)先于“migrate”運(yùn)行

二、如何得到Rake

幾年前, Jim Weirich 在一個(gè)java項(xiàng)目上使用了Make,他發(fā)現(xiàn)如果在他的Makefile中 寫一小段ruby代碼 將會(huì)帶來非常大的方便。所以他創(chuàng)建了Rake。


左:Jim Weirich,中:Jason Seifer,右:Gregg Pollack
(后面兩位為本文作者)



Jim 為Rake創(chuàng)建了任務(wù)功能,附屬關(guān)系跟蹤,甚至創(chuàng)建了時(shí)間段判斷(timestamp recognition),(在上一次編譯的基礎(chǔ)上僅編譯改動(dòng)的部分),當(dāng)然,對(duì)于ruby,我們并不需要編譯。

我很想知道Jim在代碼里做了什么,你也想知道吧。Jim可能從來沒想給這個(gè)代碼寫個(gè)文檔,可能現(xiàn)在他也是被煩透了, 寫了一個(gè) 。呵呵


三、Rake如何工作

開始我想給這個(gè)部分起名為"How to get wasted with Rake"。

那么我想喝點(diǎn)酒,該怎么做呢?

1、去買酒
2、喝酒
3、喝醉



如果我要使用Rake完成這個(gè)任務(wù),我會(huì)創(chuàng)建一個(gè)“Rakefile”文件:

    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
    
  

這樣我可以在這個(gè)Rakefile的目錄,分別運(yùn)行這些任務(wù):

    
      $
    
     rake purchaseAlcohol
    
    
    
      Purchased
    
    
      Vodka
    
    
    
    
      $
    
     rake mixDrink
    
    
    
      Mixed
    
    
      Fuzzy
    
    
      Navel
    
    
    
    
      $
    
     rake getSmashed
    
    
    
      Dood
    
    , everthing
    
      
        '
      
      
        s blurry, can I halff noth
      
      
        '
      
    
    r drinnnk?
  

酷!但是從順序上看,我可以用任何的順序運(yùn)行這個(gè)任務(wù)。比如喝醉在買酒或者喝酒之前。當(dāng)然這不符合人的習(xí)慣。


四、Rake的順序

    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?
  

看到了吧,我喝醉和,因?yàn)榫埔呀?jīng)買了,也被我喝了。(譯者:我是喜歡百事的,所以倘若我寫,定然拿百事當(dāng)例子。但是我讓我兒子和可口,為什么呢?下面告訴你。)

現(xiàn)在,你的欲望無法滿足了,你想讓你的朋友加入進(jìn)來。就像一個(gè)團(tuán)隊(duì)的開發(fā),如果你想加入一個(gè)新人,你得有合適的規(guī)劃。你得有文檔。那么問題來了。



五、如何給我的Rake添加文檔

Rake添加文檔非常的方便,使用“desc”就可以了:

    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
    
  

看到了吧,我的每個(gè)任務(wù)都添加了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
    
  

簡(jiǎn)單乎?呵呵


六、Rake的命名空間

當(dāng)你開始酗酒,并且開始使用大量的rake任務(wù)的時(shí)候,你需要一個(gè)好方法將他們分類,這時(shí)用到了命名空間,如果我在上面的例子使用了命名空間,那么:

    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
    
  

命名空間允許你將一些任務(wù)放到特定的分類中,在一個(gè)Rakefile中,你可以加入幾個(gè)命名空間。運(yùn)行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
      
    
  

所以如果想運(yùn)行這個(gè)任務(wù),只要輸入 rake alcoholic:getSmashed:


七、如何寫一個(gè)有用的ruby任務(wù)

最近,我想用ruby創(chuàng)建幾個(gè)文件夾:

    
      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
      
    
  

當(dāng)然,還可以在rake中使用更多的 文件工具 File Utils ,或者加入其他的部分。


八、如何為我的rails應(yīng)用寫一個(gè)Rake任務(wù)

一個(gè)rails應(yīng)用中,已經(jīng)有了一些rake任務(wù),你可以在你的項(xiàng)目目錄里運(yùn)行:rake --tasks。

為了給你的rails應(yīng)用添加一個(gè)新的任務(wù),你可以打開/lib/tasks目錄(已經(jīng)存在的),添加一個(gè)叫
something.rake的文件,這個(gè)任務(wù)會(huì)被自動(dòng)的檢索到,這些任務(wù)會(huì)被添加到rake tasks列表中,你可以在根目錄里運(yùn)行他們,現(xiàn)在把我們上面的例子放到這個(gè)rails應(yīng)用中。

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
    
  

注意上面的代碼,我使用了#{RAILS_ROOT} 來得到rails應(yīng)用的當(dāng)前位置,現(xiàn)在運(yùn)行“rake --tasks”,你可以看到我們的任務(wù)已經(jīng)添加到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
    
    
    
    ...
  


九、如何在任務(wù)中調(diào)用rails的model

呵呵,這個(gè)正是我最多使用rake的地方,寫一個(gè)rake任務(wù),代替原來需要手工操作的地方,或者一些任務(wù)代替經(jīng)常需要按照計(jì)劃自動(dòng)執(zhí)行(使用
cronjobs )的事情。就像我開頭說的那樣我用rake任務(wù)執(zhí)行下面的擦作:

1、給列表中的用戶發(fā)送郵件
2、每晚數(shù)據(jù)的計(jì)算和報(bào)告
3、過期或重新生成緩存
4、備份數(shù)據(jù)和svn版本( how's this : subversion repository )
5、運(yùn)行數(shù)據(jù)處理腳本(sort of,how much is called this )

這個(gè)補(bǔ)充了原來的功能,而且相當(dāng)簡(jiǎn)單。下面這個(gè)任務(wù)是檢查用戶的過期時(shí)間,對(duì)快過期的用戶發(fā)送郵件。

utils.rake

    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"

task(:send_expire_soon_emails => :environment) do

如果在我的開發(fā)環(huán)境上運(yùn)行這個(gè)任務(wù),我只需要
"rake utils:send_expire_soon_emails" ,如果我想在產(chǎn)品環(huán)境下運(yùn)行這個(gè)任務(wù),我需要 "rake RAILS_ENV=production utils:send_expire_soon_emails"

如果你想在每晚都運(yùn)行這個(gè)任務(wù),你需要寫一個(gè)
cronjob ,像這樣:

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

相當(dāng)?shù)姆奖恪?

十、在哪找到一些例子

現(xiàn)在對(duì)一個(gè)有用的rake任務(wù)已經(jīng)了解很多了,那么我將給你幾個(gè)資源,我想最好的學(xué)習(xí)方法是看看別人的代碼。

brand new rake tasks 在edge rails 中,這個(gè)可以創(chuàng)建和重置你的數(shù)據(jù)庫。

Craig Ambrose寫的數(shù)據(jù)庫備份, database backups

Adam Greene寫了一組任務(wù) set of Rake tasks ,可以將所有的數(shù)據(jù)備份到amazon S3。他還給了我一個(gè)升級(jí)版本,你可以在這下載 here

Jay Fields的任務(wù)測(cè)試, testing rake tasks

a new way of setting the RAILS_ENV and teaches how to use rake to boot you into a Mysql shell (看的時(shí)候留意一下他的注釋)

Rake Bookshelf Books ,和Martin Fowler的 Using the Rake Build Language 教程,這兩個(gè)都很有用,雖然有點(diǎn)過時(shí)。

Ruby on Rails中的Rake教程


更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號(hào)聯(lián)系: 360901061

您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺我的文章對(duì)您有幫助,請(qǐng)用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長(zhǎng)非常感激您!手機(jī)微信長(zhǎng)按不能支付解決辦法:請(qǐng)將微信支付二維碼保存到相冊(cè),切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對(duì)您有幫助就好】

您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺我的文章對(duì)您有幫助,請(qǐng)用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長(zhǎng)會(huì)非常 感謝您的哦!!!

發(fā)表我的評(píng)論
最新評(píng)論 總共0條評(píng)論
主站蜘蛛池模板: 国产在线一区在线视频 | 亚洲综合色就色手机在线观看 | 精品国产成人综合久久小说 | 九九精品热 | 老头与老头同性tube可播放 | 亚洲播放 | 天天摸夜夜摸夜夜狠狠摸 | 成人免费xxx色视频 成人免费播放视频777777 | 9久9久热精品视频在线观看 | 91麻豆精品国产91久久久久 | 日韩欧美中文字幕一区 | 国产做爰免费视频观看 | 日韩免费在线观看 | 国产亚洲精品一区二区在线播放 | 99久久精品免费观看区一 | 久久精品国产只有精品6 | 国产高清在线精品一区a | 国产精品真实对白精彩久久 | 免费xxxx美国18 | 久久精品国产亚洲麻豆小说 | 久久96国产精品久久久 | 91精品啪在线观看国产老湿机 | 国产精品成人观看视频国产奇米 | 五月婷婷网站 | 天天做天天爱天天爽天天综合 | 亚洲综合一区二区 | 亚洲美女视频免费 | 欧美在线一级毛片观看 | 国产精品一区在线播放 | 亚洲精品乱码久久久久久蜜桃 | 精品精品国产高清a毛片牛牛 | 老司机午夜免费影院 | 毛片一区二区三区 | 国产美女精品在线观看 | 国外成人免费视频 | 国内拍拍自拍视频在线观看 | 国内高清久久久久久久久 | 亚洲无线码一区在线观看 | 一级看片| 九九精品热 | 伊人影院在线视频 |