Software engineering notes

Rails Seeds

Introduction

Fabrication

一個 model 對應一個 fabrication

首先先建立模型

Fabricator(:person) do
  age { rand(20..45) }
end

一定要用 { } 包起來,因為有遇過一些奇怪的 bug, 而 seed 不成功

Insert 資料

Fabricate(:person)
Fabricate(:person, email: 'xxx@ff.com')     # 指定欄位

Faker 使用上非常簡單, 直接看 Example

建立 4 個 users, 並且每名 user 指定一個 role, 隨機 user 建立共 50 篇文章, 隨機 user 對隨機挑的 50 篇文章回覆共 200 筆留言

user = User.create({email: "user@gmail.com", password: "00000000", confirmed_at: Time.now})

Fabricator(:post) do
  title { Faker::Lorem.sentence(3, true, 4) }
  content { Faker::Lorem.paragraph(4, true, 7) }
end

50.times { Fabricate(:post, user_id: user.id) }

Fabricator 的 Table name 要用單數

Seed file with paperclip

Fabricator(:product) do
  photo { File.new("app/assets/images/logo.png") }

  或傳入一個 url
  photo { open("http://lorempixel.com/300/300/") }
end

建議可以區分 Seed 的環境, 避免 Seed 到 Production

case Rails.env
when "development"
   ...
when "production"
   ...
end

Locale

Faker 在不同機器可能會讀取到不同的 locale, 例如我在開發機是 en 的, 但到 production 卻變成 zh-TW, 而 Faker::Internet.free_email 卻變得不 work 了

但可以在 config 裡設定他預設的 locale

config/environments/development.rb :

Faker::Config.locale = 'en'

Troubleshootings

ActiveRecord::RecordNotSaved: You cannot call create unless the parent is saved

有可能會發生在當一筆資料沒有建立成功(可能是 validation 沒有通過),造成資料沒有建立,但又直接建立關聯資料造成的錯誤:

c = Category.create(...)
c.products.create(...)

建議加上 ! 讓錯誤當下直接擲出 Exception 中斷程序

c = Category.create!(...)
c.products.create!(...)