【Rails】1対多の大量のダミーデータをFakerとinsert_allで作成する

Ruby

アプリケーションの性能や検証をする際に、1対多の関係を持つダミーデータを大量に用意したい時があります。

Rails 6から利用できるinsert_allメソッドを利用すると大量のデータを短時間でインサートできます。
また、Fakerを利用することでダミーデータを生成できます。

今回はinsert_allとFakerを利用して1対多のデータを大量に作成する方法について紹介します。

今回作るダミーデータの要件

  • Authorモデルとそれに紐づくBookモデルを作成
  • Authorモデルに紐づくBookモデルの数はランダム
  • Authorモデルの属性はfirst_nameとlast_name
  • Bookデモルの属性はtitleとprice
  • Bookモデルのpriceは500 ~ 1,000のランダムな値。刻み幅は10
  • authorsテーブルには1万件、booksテーブルには3万件のレコードを作成する

Fakerのインストール

Gemfile

group :development, :test do
  gem 'faker'
end
$ bundle

モデルとテーブルの作成

1対多の関係を持つAuthorモデルとBookモデルを作成します。

$ rails g model Author first_name last_name
$ rails g model Book title price:integer author:references

モデル作成後、マイグレーションを実行します。

$ rails db:migrate

seedsファイルの作成

今回は初期データとしてダミーデータを作成するためseeds.rbを活用しますが、コンソールから直接実行しても問題ありません。

seeds.rb

AUTHOR_NUMBER = 10_000
authors = []
AUTHOR_NUMBER.times do |n|
  time = Time.current
  authors <<
    {
      first_name: Faker::Name.first_name,
      last_name: Faker::Name.last_name,
      created_at: time,
      updated_at: time
    }
end
Author.insert_all authors

books = []
30_000.times do |n|
  time = Time.current
  books <<
    {
      title: Faker::Book.title,
      price: "rand(50..100) * 10,
      author_id: "#{ rand(1..AUTHOR_NUMBER) }",
      created_at: time,
      updated_at: time
    }
end
Book.insert_all books

ダミーデータのインサートを実行

### seedデータをテーブルにインサート
$ rails db:seed


### seedデータのインサートをやり直したい場合
$ rails db:migrate:reset
$ rails db:seed

インサート実行後、テーブルを確認するとダミーデータが挿入されていることがわかります。

$ select * from authors;

+----+------------+-----------+----------------------------+----------------------------+
| id | first_name | last_name | created_at                 | updated_at                 |
+----+------------+-----------+----------------------------+----------------------------+
|  1 | Juana      | Weber     | 2021-05-27 12:58:13.176500 | 2021-05-27 12:58:13.176500 |
|  2 | Ida        | Wehner    | 2021-05-27 12:58:13.506941 | 2021-05-27 12:58:13.506941 |
|  3 | Federico   | Bernhard  | 2021-05-27 12:58:13.507398 | 2021-05-27 12:58:13.507398 |
...
...
|  9998 | Sang        | Harvey        | 2021-05-27 12:58:16.991960 | 2021-05-27 12:58:16.991960 |
|  9999 | Sandra      | Wilkinson     | 2021-05-27 12:58:16.992319 | 2021-05-27 12:58:16.992319 |
| 10000 | Harley      | Hoppe         | 2021-05-27 12:58:16.992598 | 2021-05-27 12:58:16.992598 |
+-------+-------------+---------------+----------------------------+----------------------------+
$ select * from books

+----+---------------------------------+-------+-----------+----------------------------+----------------------------+
| id | title                           | price | author_id | created_at                 | updated_at                 |
+----+---------------------------------+-------+-----------+----------------------------+----------------------------+
|  1 | A Time to Kill                  | 880   |      3367 | 2021-05-27 14:23:31.771847 | 2021-05-27 14:23:31.771847 |
|  2 | I Know Why the Caged Bird Sings | 900   |      2854 | 2021-05-27 14:23:31.772004 | 2021-05-27 14:23:31.772004 |
|  3 | Paths of Glory                  | 850   |      5324 | 2021-05-27 14:23:31.772504 | 2021-05-27 14:23:31.772504 |
...
...
| 29998 | The Soldier Art          | 720   |      5724 | 2021-05-27 14:23:34.210723 | 2021-05-27 14:23:34.210723 |
| 29999 | The Sun Also Rises       | 840   |      3675 | 2021-05-27 14:23:34.210787 | 2021-05-27 14:23:34.210787 |
| 30000 | The Glory the Dream      | 550   |      3207 | 2021-05-27 14:23:34.210857 | 2021-05-27 14:23:34.210857 |
+-------+--------------------------+-------+-----------+----------------------------+----------------------------+

さいごに

Twitter(@nishina555)やってます。フォローしてもらえるとうれしいです!