還記得在建立rails 的 database時,我們跑過
rake db:create # 依照目前的 RAILS_ENV 環境建立資料庫
rake db:migrate # 執行Migration動作
所以...
在介紹rake前,先介紹make
make是一個工具程式(Utility software),經由讀取叫做「makefile」的檔案,自動化建構軟體。詳情可以看make Wiki
Rake 是 Ruby 版的Make,是 Ruby 的任務腳本,讓我們在CLI中可以執行。提供良好的任務編寫結構,且很方便設定各個任務的相依性,或是搭配像是whenever gem 就可以排程執行任務。
Rake藉由讀取叫做Rakefile 或 rakefile的檔案來執行任務腳本,而這些任務腳本就是所謂的task。在 Rails 環境中撰寫 Rake,請將附檔名命名為.rake
,並將檔案放在 lib/tasks
目錄下,例如:
task :ironman do
puts '我要寫三十篇'
end
透過task
這個方法定義 task_name。像是ironman
就是這個task的名稱;接著使用block,並把想要執行的Ruby程式碼放在裡面
要執行這個task的話,只要在console下rake task_name
,像這樣:
rake ironman
# => 我要寫三十篇
想知道目前有哪些 rake 可以用,只要在console下
rake -T # rake --task 也可以,rake -T 是縮寫
有偵探精神的人一定覺得奇怪,怎麼沒有剛才建立的:ironman
task?
rake -T預設只會列出有 description的task,所以如果你希望定義的task在列表中顯示的話,可以在task上方使用desc method來加入描述:
desc '30 days ironmon'
task :ironman do
puts '我要寫三十篇'
end
再下一次rake -T
:
有了 (๑•̀ㅂ•́)و✧
namespace 常用來區隔不同情況卻有相同名稱task。例如不同的情況下分別定義兩個create的task,但是當我們呼叫create
的時候可能會產生不必要的麻煩,就可以透過namespace來避免這個問題。
namespace :ithelp do
desc '30 days ironmon'
task :ironman do
puts '我要寫三十篇'
end
end
在console執行時,也要加上namespace
rake ithelp:ironman
# => 我要寫三十篇
執行rake -T
:
可以看到多了前綴字,ithelp
。
也就可以理解為什麼用rake -T
列出rake時,大部分的rake 名稱都有:
,不然db:create
跟tmp:create
,如果都只有create
這個task name,Rails 也會被你搞混。
如果 task 在執行前必須要有前置作業( prerequests ),也就是執行 task_b 前要先執行task_a,可以在task_name後面再放一個task_name,像這樣:
desc 'task_a'
task :task_a do
puts 'task_a'
end
desc 'task_b'
task task_b: :task_a do
puts 'task_b'
end
輸出結果:
task_a #先執行 task_a
task_b
如果有多個前置作業要執行,也可以用矩陣的方式
desc 'task_b'
task task_b: [:task_a, :task_c] do
puts 'task_b'
end
那麼會以 :task_a => :task_c => :task_b 的順序執行。
一般的task並沒有載入環境中的model,可以透過先執行:environment
這個 rails 預設的 task來載入 DB 環境。
desc 'Product titles'
task product_titles: :environment do
puts Product.pluck(:title)
end
執行後可以得到
商品一
七代目火影
如果拿掉:environment 會噴這個錯:
如果rake 要帶入參數,就在task_name後面給一個以Symbol為元素的矩陣,然後在 block 內就可以呼叫args
這個參數集合
desc 'Example of task with parameters and prerequisites'
task :my_task, %i[first_arg second_arg] do |t, args|
args.with_defaults(second_arg: 'Bar') #設定second_arg的預設值為"Bar"
puts "First argument was: #{args.first_arg}"
puts "Second argument was: #{args.second_arg}"
end
執行這個task 時,因為有帶參數,rake_name跟參數矩陣要用括號包起來
rake "my_task[one,two]"
輸出結果:
First argument was: one
Second argument was: two
block 內部的args
其實是Rake::TaskArguments
的實體,如果在task block 設中斷點byebug
看args
會長這樣:
#<Rake::TaskArguments second_arg: two, first_arg: one>
可以透過兩種方式args[:first_arg]
或args.first_arg
來取第一個參數"one"
上面的my_task block內呼叫#with_defaults
方法就可以 hash 形式設定特定參數預設值:
args.with_defaults(second_arg: 'Bar')
前面提到如果想執行其他rake,可以放在前置作業去執行,但是
不想放在前置作業執行呢?
就要使用Rake::Task['task_name'].invoke
:
desc 'task_b'
task task_b: [:task_a, :task_c] do
puts 'task_b'
Rake::Task['ithelp:ironman'].invoke
end
輸出
task_a
task_c
task_b
我要寫三十篇
我要寫三十篇
rake會預設在development的環境下執行。如果你需要指定執行環境的話,透過RAILS_ENV=your_environment的指令來指定。
rake db:schema:dump RAILS_ENV=production
提醒一下,rails server 不载入 .rake 文件,所以在 rails console 或是 runtime 時,都不能執行rake。
可惜斷惹!!!
謝謝你的欣賞
後來一忙就沒繼續寫了
我答應你今年會補滿30篇
今年又補上8篇技術文章了
https://ithelp.ithome.com.tw/users/20109080/ironman/3705
有達成承諾了,謝謝阿展
來年再拚!!
欸不對 今年戰鬥中!! 衝啊!!!