コード日進月歩

しんくうの技術的な小話、メモ、つれづれ、など

FactoryBotでbelongs_toの相手がいる場合はidではなくモデルを代入しましょう

日曜日ということもあり なるほど、こういう見解もあるのか。 という天然の間違いに関しての発見メモ。

環境

$ bin/rails -v
Rails 5.2.2

事例

例えばこんなModelがあるとする(Modelの値はannotateのgemで表現)

# == Schema Information
#
# Table name: messages
#
#  id         :bigint(8)        not null, primary key
#  name       :string(255)
#  user_id    :integer
#  created_at :datetime         not null
#  updated_at :datetime         not null
#

class Message < ApplicationRecord
  belongs_to :user
end

このFactoryBotがあったのだが、以下のように記載があった

FactoryBot.define do
  factory :message do
    sequence(:user_id) {|i| }
    name {"example message no:#{rand(200)}"}
  end
end

この事例の悪いところ

  • userがいるかいないかわからない状態なのにidだけをとりあえず入れている
  • userが連動して作られているか保証されていない

修正の方針

belongs_to で指定しているので、基本はひも付き先のレコードは要ることが大前提になるので期待に沿うようにつくってあげる

UserモデルのFactoryBotが定義されていれば、それを明示的に書くだけでレコードは作られる

FactoryBot.define do
  factory :message do
    user 
    name {"example message no:#{rand(200)}"}
  end
end

参考サイト

上記より

FactoryBotでモデルを作成する際に、関連しているモデルも同時に作成することができる。

対象の関連がbelongs_toであれば特に問題はないが、has_manyの関連を扱う場合には注意が必要になる。

例として、UserとPostが一対多だったとしてFactoryBotでの定義を書いてみる。

あたりを参考にした。