iT邦幫忙

1

Rails幼幼班--由seeds認識Rake

  • 分享至 

  • xImage
  •  

什麼時候知道自己已經是大叔了...從看到國民妹妹會露出姨母笑時...

Yes


或許這部分比較簡單,網路上查不到太多中文資料,自己紀錄筆記一下。

seeds在哪裏?

專案中:project_name/db/seeds.rb
與Migrate這些資料放在一起,之前有簡單操作過Migration,主要是在建立資料部分,當然seeds也與此相關。

當我們於專案中,用Rails console來操作建立新資料。(練習請用Rails console --sandbox)

#Model_name.new
2.7.3 :001 > Player.new
 => #<Player id: nil, name: nil, power: nil, country: nil, created_at: nil, updated_at: nil, level: 2> 
#可以發現,除了level我有給預設的value外,其餘值都是nil,代表只是給了一個"殼"。

Create與Save差異在於有沒有自動接save,new沒有。

#Model_name.create
2.7.3 :002 > Player.create
#略過一段程式碼。
 => #<Player id: 21, name: nil, power: nil, country: nil, created_at: "2021-08-20 06:17:11.601626000 +0000", updated_at: "2021-08-20 06:17:11.601626000 +0000", level: 2> 
#框架中,action: create未做處理前,直接會執行action: save。

一樣可以發現除了Rails中預設會給資料的id與timestamps外,其餘資料還是nil。

假設我想有內容物的資料怎麼辦?

當然是給參數。

2.7.3 :007 > Player.create(name: "大叔", power: 10, country: "台北", level: 3)
  #略
  TRANSACTION (0.1ms)  RELEASE SAVEPOINT active_record_1
 => #<Player id: 25, name: "大叔", power: 10, country: "台北", created_at: "2021-08-20 06:31:34.412628000 +0000", updated_at: "2021-08-20 06:31:34.412628000 +0000", level: 3> 
 #預設值一樣可以手動給,預設值比較像,先設定好一個值,如果我們沒給會給那個值

假設我想一次建立10筆怎麼辦?

那就輸入10次..
會這麼勤勞有鬼...

2.7.3 :008 > 10.times do Player.create end
#中間跑一大段英文,有10段重複的...略
=> 10 #還貼心回傳個10,代表跑完了

那假設我有三個model,都想建立10筆資料怎麼辦

$ 10.times do Model_name.create end
$ 10.times do Model_name.create end
$ 10.times do Model_name.create end

好的,不可能這麼麻煩。

seeds

內建Rake指令之一(預設無內容),用於後臺快速建立資料。

#project_name/db/seeds.rb

10.times do
  Player.create(name: "大叔", power: 2, country: "台北")
end

puts "跑完了"  #可加可不加,習慣有提示所以加。

於rails console,執行

$ rails db:seed 

正常會跑出"跑完了",再去資料庫查看,或以指令查,可以發現建立好10筆大叔資料了。
所以當要建立測試資料,也不可能去view真的操作10次,以seeds來處理。

補充Ruby on Rails Guides

5.times do |i|
  Product.create(name: "Product ##{i}", description: "A product.")
end
# 透過語法當然可以創建內容較不同的資料。

創建內容不同的假資料:Faker

gem。
安裝後我們先於irb操作。

$ require 'faker'  #gem為第三方函式庫,使用前須require。
=> true    #跳false當然代表失敗,先確認有無正確安裝吧。

$ Faker::Game.title
=> "Bayonetta"  

$ Faker::Games::Heroes.name
 => "Moandor" 

Bayonetta...剛好是喜歡的遊戲,傳教一下...

先不論看不看得懂指令原理,可以知道經過Faker這個gem,可以創建許多"資料"。
當然有些資料很明顯是內建打包好的。

於rails console操作,如有正確安裝於gemfile並bundle,gem會屬於專案本身一部分,不需要require。

$ Player.create(name: Faker::Name.name)
=> #<Player id: 43, name: "Lacy Farrell", power: nil, country: nil, created_at: "2021-08-20 07:42:40.736607000 +0000", updated_at: "2021-08-20 07:42:40.736607000 +0000", level: 2> 

$ Player.create(name: Faker::Name.name, power: rand(4..10), country: Faker::Address.
country)
=> #<Player id: 45, name: "Cleo Abbott", 
                    power: 6, 
                    country: "Kyrgyz Republic", 
                    created_at: "2021-08-20 07:46:33.362240000 +0000", 
                    updated_at: "2021-08-20 07:46:33.362240000 +0000", 
                    level: 2> 

所以將指令搬到seeds.rb。
當指令多時,以後只需要一個指令完成。

10.times do
  Player.create(
    name: Faker::Name.name,
    power: rand(4..10),
    country: Faker::Address.country)
end

puts "跑完了"

如果想建立其他語系資料,需先改Faker的locales,seeds.rb直接加入下面這段即可。

Faker::Config.locale = "zh-TW"

10.times do
  Player.create(
    name: Faker::Name.nam
    略....

Faker支援語系https://github.com/faker-ruby/faker/tree/master/lib/locales
繁體中文支援哪些資料(不支援的一樣只會給英文)。
https://github.com/faker-ruby/faker/blob/master/lib/locales/zh-TW.yml


Rake

上面其實已經講解完怎麼操作,及內容怎麼寫。(用Ruby寫...)
不過seeds.rb其實是透過 rails db:seed 這指令來執行其內容,實際編寫還是有不同的地方。

維基百科:

Rake是一款軟體任務管理及組建自動化工具。用戶可指定任務、描述依賴關係及分組命名空間中的任務。
Rake使用Ruby編寫,使用以Ruby語法編寫的Rakefile。
Rake使用Ruby的匿名函數塊來定義多個任務並允許用戶使用Ruby語法。

Rake其實就是"腳本"或"任務"。

請於專案下執行

$ rails -T    #rake -T 也可。

出現的那一堆就是已經內建好的rake,應該說建立好的"task"

補充:不加 -T,rake指令不會有描述檔,還會出現generate, console等指令。
-T,代表叫出有描述檔的。(description)

建立自己的task

project_name/lib/tasks 這個資料夾,為存放處。
副檔案名以".rake"命名。

# project_name/lib/tasks/rake_demo01.rake
task :rake_name_free do
  puts "偷懶就用Hello world"
end

存擋後執行

$ rails rake_name_free
=> 偷懶就用Hello world

為了方便加入description

沒加入description前,rails -T裡面是不會出現自己建立的task的。
加入方式。

# project_name/lib/tasks/rake_demo01.rake
desc "人生第一隻rake..."   #就這麼簡單
task :rake_name_free do  
  puts "偷懶就用Hello world"
end
$ rails -T

https://ithelp.ithome.com.tw/upload/images/20210820/20135887Kw8Jjzw7nw.png

如果連description都不夠用? namespace!

其實是,可能在方法命名上,內容即使不同,但命名的靈感已經不夠時,可以用namespace這個方法處理。
首先建立兩個檔案

# project_name/lib/tasks/rake_demo01.rake
desc "人生第一隻rake..."
task :rake_test do
  puts "偷懶就用Hello world"
end
# project_name/lib/tasks/rake_demo01.rake
desc "人生第二隻rake..."
task :rake_test do
  puts "繼續偷懶就繼續用Hello world"
end

執行

$ rails -T

會發現只有一個rake,兩個描述。
https://ithelp.ithome.com.tw/upload/images/20210820/201358873zHJrMzp1X.png

執行會發現

$ rails rake_name_free 
偷懶就用Hello world
繼續偷懶就繼續用Hello world

兩個都會跑,如果是想這樣一次跑兩個rake....
可以,但通常不這樣做,等等提。

先以namespace處理。

namespace :this_is_two do
  desc "人生第二隻rake..."
  task :rake_name_free do
    puts "繼續偷懶就繼續用Hello world"
  end
end

存擋執行rails -T,會發現。
https://ithelp.ithome.com.tw/upload/images/20210820/20135887LLFj8BRnAt.png

$ rails this_is_two:rake_name_free
繼續偷懶就繼續用Hello world

一個rake執行複數rake

檔案內容先做修改

#first.rake
desc "人生第一隻rake..."
task :rake_name_free do
puts "偷懶就用Hello world"
end

#second.rake
desc "人生第二隻rake..."
task :rake_two do
puts "繼續偷懶就繼續用Hello world"
end

方法一,用第三個rake執行這兩個。

在建立一個新檔案。

# 我不會數三.rb
desc "G胖不會數3"
task :rake_three => ["rake_name_free","rake_two"]
$ rails rake_three               
偷懶就用Hello world
繼續偷懶就繼續用Hello world

方法二,execute

將first.rake修改

task :rake_name_free do
  puts "偷懶就用Hello world"
  Rake::Task["rake_two"].execute
end

#執行
$ rails rake_name_free  
偷懶就用Hello world
繼續偷懶就繼續用Hello world

衍生:Rake Task中Invoke, Execute, Enhance差異
超過幼幼班等級,不想介紹...

最後

Rake tasks都預設是在development環境下操作,當然可以把指令改在其他環境操作。
不過目前部署網站都支援,可以設定指定task,所以查找各部署網站教學比較適合。


邏輯笑話?:
我以為切洋蔥時閉眼睛就不會流眼淚了,但是我手流血了~


圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言