FactoryBot 関連データの作成
FactoryBotにおけるアソシエーション
belongs_toとhas_many ※ 解釈が合っているか分からない
- 所属(belongs_to)先を記載する場合はFactoryBotに
association: author
(associationは省略可)みたいに記載すればいい - has_manyの場合はassociationによる記載が使えないのでtraitやコールバックを用いて、後から関連データを入れ込む形
FactoryBot.define do factory :article do sequence(:title, "title_1") sequence(:slug, "slug_1") # belogns_toのリレーションのみ以下の記載が可能? category author # has_manyリレーションではassciationは使えないので、authorやtagの場合はtraitとコールバックであるafter(:create)を使う end
transientとコールバック after build
callback…特定の瞬間に呼び出されるメソッド
# articleのFactory続き # traitを用いてhas_manyリレーションを入れ込む trait :with_author do transient do sequence(:author_name, 'test_author_name_1') sequence(:tag_slug, 'test_author_slug_1') end after(:build) do |article, evaluator| article.author = build(:author, name: evaluator.author_name, slug: evaluator.tag_slug) end end
- transientは実際に作成するデータと直接関係がない変数を定義する機能
- モデルの属性以外のデータをファクトリに含めることができる
- 作成時に挙動を変更するためのフラグや追加データとして利用する
■ after(:build)は何をしているのか。evaluatorって何者?
コールバックを使うことで生成したインスタンスがcreate,buildされたイベントの直後に自由にインスタンスを修正できる。
- つまり
after(:build) do |article, evaluator|
というブロックでは、コールバックによってarticleインスタンスが作られた後に、article.authorの値に修正が加えられている
after(:build) do |article, evaluator| article.author = build(:author, name: evaluator.author_name, slug: evaluator.tag_slug) end
↑割と素直にコードを読んで良いんだなと思った。
- after(:build) do |article|でarticleインスタンスが作られた後、ブロック内でarticle.authorの名前をtransientで生成したものに修正している
- 第二引数の
evaluator
を渡すことで、transient
ブロック内の変数にアクセスできる
→この仕組みは、rails newコマンドでなぜ色んなファイルができるのか?みたいなレベルのお話になってくるので考えなくて良いとのこと◎
参考にしたサイト
FactoryGirlのtransientとtraitを活用する - Qiita