🦓

[Rails]ダミーデータを作る12/20

2023/06/30に公開

はじめに

FakerFactoryBotを使ってダミーデータを作成していきます。

環境:

Rails 6.1.7.3
ruby 3.0.0

Fakerとは

Fakerは、開発やテスト目的で使用される偽のデータを生成するためのRubyのgemです。これにより、テストデータの作成や開発中のサンプルデータの生成など、さまざまな目的に活用することができます。
Fakerはランダムにデータを生成しますが、返される値はデフォルトではユニークであることが保証されていません。一意の値が必要な場合は、明示的にuniqueと指定する必要があります。
https://github.com/faker-ruby/faker

seeds.rbとは

seeds.rbは、Railsで初期データを作成するためのファイルです。このファイルに記述されたコードは、データベースに初期データを投入する際に使用されます。通常、開発環境やテスト環境でのデータ作成や、デモデータの準備などに利用されます。

seeds.rbファイルはRailsのdb/seeds.rbに配置されています。
一般的な使い方としては、データモデルを作成し、それに対する属性値を指定してデータベースに保存する処理を記述します。

# ユーザーデータの作成
User.create(name: 'John Doe', email: 'john@example.com', password: 'password')

# 記事データの作成
Post.create(title: 'First Post', body: 'Lorem ipsum dolor sit amet.')

# コメントデータの作成
post = Post.first
post.comments.create(author: 'Jane Smith', body: 'Great post!')

上記の例では、ユーザー、記事、コメントの初期データを作成しています。createメソッドを使用してモデルのインスタンスを作成し、属性値を指定してデータベースに保存しています。

seeds.rbファイルに記述したデータ作成のコードは、以下のコマンドを使用してデータベースに投入することができます:

rails db:seed

このコマンドを実行すると、seeds.rbファイル内のコードが順に実行され、データベースに初期データが作成されます。

インストール

Fakerdevelopmenttestどちらの環境にも使用できるようにGemfileにて記載します。

Gemfile
  group :development, :test do
    gem 'faker'
  end
bundle install

seeds.rbを編集する

ユーザーと投稿のダミーデータを作成します。

db/seeds.rb
10.times do
    User.creste!(
        user_name: Faker::Internet.username
        email: Faker::Internet.unique.email
        password: 'password',
        password_confirmation: 'password'
    )
end

20.times do |index|
    Article.create!(
      user: User.offset(rand(User.count)).first,
      title: "タイトル#{index}",
      body: "本文#{index}"
    )
  end
bin/rails db:seed

ダミーデータを作成されたことを確認します。

irb(main):001:0> Faker::Internet.username
=> "tyrone.kuhic"
irb(main):002:0> Faker::Internet.email
=> "elden.sporer@schoen.example"

create!

createtruefalseを返すメソッドなので、userの作成に失敗した場合もエラーを出してくれません。なので、user作成失敗時に例外を発生させるcreate!を選択します。

User.offset(rand(User.count)).first

User.offset(rand(User.count)).first は、ランダムにデータベースの User モデルから1つのレコードを取得するためのコードです。

  1. User.count は、データベース内の User モデルのレコード数を返します。
  2. rand(User.count) は、0から User モデルのレコード数の範囲でランダムな整数を生成します。これによって、ランダムなオフセット値が得られます。
  3. User.offset(rand(User.count)) は、ランダムなオフセット値を指定して User モデルのレコードを一つ取得します。
  4. first メソッドは、取得したレコードの中で最初の1つを返します。

https://github.com/faker-ruby/faker/blob/main/doc/default/internet.md

FactoryBot

FactoryBotはテストデータの作成を効率化するための便利なツールです。

  1. Factoryの定義: FactoryBotで使用するファクトリを定義します。ファクトリはモデルごとに定義され、デフォルトの属性値や関連データなどを指定します。
spec/factories/user.rb
# 例: Userモデルのファクトリ定義
FactoryBot.define do
  factory :user do
    name { Faker::Name.name }
    email { Faker::Internet.unique.email }
    password { 'password' }
  end
end

# sequenceを使ってユニークな値を生成する
FactoryBot.define do
  factory :user do
    name { 'user' }
    sequence(:email) { |n| 'user_#{n}#example.com' }
    password { 'password' }
    password_confirmation { 'password' }
  end
end
  1. テストデータの生成: FactoryBotを使用してテストデータを生成します。createメソッドを使用するとデータベースに保存され、buildメソッドを使用すると保存されずにインスタンスが作成されます。
# ファクトリからテストデータを生成する例
user = FactoryBot.create(:user)
# or
user = FactoryBot.build(:user)

# name属性を指定してテストデータを生成する例
user = FactoryBot.create(:user, name: 'John Doe')

複数のテストデータを作成することもできます。

  1. create_listメソッドを使用する方法:
users = FactoryBot.create_list(:user, 5)
  1. 繰り返し処理を使用する方法:
5.times do
  FactoryBot.create(:user)
end
  1. 属性のオーバーライドを使用する方法:
5.times do |n|
  FactoryBot.create(:user, name: "User #{n+1}")
end

https://github.com/thoughtbot/factory_bot_rails

インストール

Gemfile
  group :development, :test do
    gem 'factory_bot_rails'
  end
bundle install

ファクトリーのファイルをモデルごとにデフォルトで作成しない

ジェネレーターを

config/application.rb
config.generators do |g|
  g.factory_bot false
end

テストケースでテータを作成する

rspec/models/user_spec.rb
RSpec.describe User, type: :model do
  it 'creates a new user' do
    user = FactoryBot.create(:user)
    # テストコードの残り部分
  end
end

FactoryBot.create(:user)を使用して、userモデルのインスタンスを作成しています。FactoryBotFactoryの定義に基づいて適切なデータを生成し、データベースに保存します。

FactoryBotの省略設定

spec/rails_helper.rb
RSpec.configure do |config|
  config.include FactoryBot::Syntax::Methods
end

通常、FactoryBotのデータを呼び出す際は、FactoryBot.create(:user) のような書き方をします。

上記の設定をすることで、先頭に記述しているFactoryBot. を省略してcreate(:user)だけで記述できるようになります。

終わりに

FactoryBotとFakerは異なる役割を持ち、テストデータの生成において補完的な役割を果たします。FactoryBotを使用してデータの構造を定義し、Fakerを使用して具体的なデータの値を生成することで、柔軟かつリアルなテストデータを作成することができますね。

https://qiita.com/takehanKosuke/items/79a66751fe95010ea5ee
https://zenn.dev/yukihaga/articles/e0cf573f3c545e
https://qiita.com/sazumy/items/4006bd868affa535adb0

Discussion