# [Rails]如何使用 task 自動產生假資料
###### tags: `Ruby` `Rails` `rake`
## 目標
使用 rake 產生 user 假資料。
## 環境
- ruby 2.6.5
- rails 6.0.3.2
## 套件
- gem 'faker', '~> 2.13'
- gem 'carrierwave', '~> 2.1'
- gem 'figaro', '~> 1.0'
## 前置動作
準備移一個有 User model 的 rails 專案
## 實作
### Step 1: 建立任務檔案
在專案 `lib/tasks` 資料夾建立一個 `rake` 檔用來寫需要產生的假資料。

### Step 2: 加入任務分類
現在要做的任務如同在建立或修改 db 內容時執行的 `rails db:migrate` 一樣,可以在任務外面家上 `namespace` 中讓分類關係更明確
```=ruby
namespace :dev do
end
```
### Step 3: 引入 User model
這裡預設專案中已經有 User model 才可以用 `environment` 引入 `model` 產生資料
```=ruby
namespace :dev do
task fake_users: :environment do
end
end
```
### Step 4: 使用 api 取得使用者資料
註冊 api 網站 => [UI Faces](https://uifaces.co/api-key) 取得 api key,即可使用網站提供的資料。
避免密碼外洩,api key 可以使用 [figaro](https://github.com/laserlemon/figaro) 設定成環境變數。
### Step 5: 使用 rails 請求 api 資料
引入 rails 的請求功能,依照 api 使用方式,取得資料。
取得回傳結果後,使用 `JSON.parse` 把得到結果後轉為 `json` 格式。
```=ruby
COUNT = 10
uri = URI("https://uifaces.co/api?limit=#{COUNT}")
req = Net::HTTP::Get.new(uri)
req['X-API-KEY'] = ENV["UI_face_X_API_KEY"]
response = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
http.request(req)
end
users = JSON.parse(response.body)
```
### Step 6: 建立新 user
依照 user 需要的欄位和想要的假資料格式加入資料
```=ruby
User.create!(
nick_name: user["name"].split(" ").join.downcase ,
email: user["email"],
password: "123456",
description: Faker::Lorem.sentence,
remote_avatar_url: user["photo"] #carrierwave
)
```
#`remote_avatar_url` 是 `carrierwave` 用來設定圖片的方法
### Step 7: 加入產生訊息
直接執行任務不會有訊息表示執行情況,可以在執行中加入訊息
```=ruby
task fake_users: :environment do
print "\n正在建立使用者資料"
User.destroy_all
COUNT = 10
uri = URI("https://uifaces.co/api?limit=#{COUNT}")
req = Net::HTTP::Get.new(uri)
req['X-API-KEY'] = ENV["UI_face_X_API_KEY"]
response = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
http.request(req)
end
users = JSON.parse(response.body)
users.each do |user|
User.create!(
nick_name: user["name"].split(" ").join.downcase ,
email: user["email"],
password: "123456",
description: Faker::Lorem.sentence,
remote_avatar_url: user["photo"] #carrierwave
)
print "."
end
puts "\n成功建立 #{User.count} 筆 使用者資料!"
puts User.last.email
end
```
### Step 8: 測試 & 執行
打開終端機到專案位置,使用以下指令執行任務
```
rails dev:fake_users
```
## 延伸
### 同時執行多個任務
rails 提供了 invoke 方法可以在任務中執行任務
當有多個任務時可以寫成以下樣子,既可以執行單一任務,也一次執行所有任務
```=ruby
#其他任務
.
.
.
task fake_all: :environment do
Rake::Task["dev:fake_users"].invoke
Rake::Task["dev:fake_follows"].invoke
Rake::Task["dev:fake_posts"].invoke
end
```