ファクトリーガール(ボット)連想

今回は、ファクトリーガールを使ってhas_one、has_many、polymorphic連想のデータを生成する方法について説明します。

has_one関連データの生成

has_one関連を設定するのは非常に簡単で、ファクトリー内で定義できます。 ファクトリー名がアソシエーション名と同じであれば、ファクトリー名を省略することができます。 たとえば:

FactoryBot.define do factory :story do # story attributes author endend

また、別のファクトリーを指定して属性を上書きすることもできます:

FactoryBot.define do factory :story do # story attributes association :author, factory: :user, first_name: "Jon" endend

関連を作成するための異なる戦略を指定することもできます:

association :author, factory: :user, strategy: :build

これではデータベースに関連オブジェクトを保存できないことに留意してください。

has_many 関連付けのデータを生成する

has_many 関連付けのデータを生成するのは、少し複雑です。 新しいファクトリーを定義し、after(:create)コールバックを使ってアソシエーションのリストを作成することができます。 この例でその方法を見てみましょう。

FactoryBot.define do # user factory without associated stories factory :user do # user attributes factory :user_with_stories do transient do stories_count 10 end after(:create) do |user, evaluator| create_list(:stories, evaluator.stories_count, user: user) end end endend

属性 stories_count は一時的なもので、ファクトリーの属性および評価器を経由したコールバックで使用できます。

create(:user_with_stories).stories.length # 10create(:user_with_stories, stories_count: 15).stories.length # 15

すべてのストーリーは一意の ID を持ちますが、他の属性を一意にするために、各ストーリーに対して異なる値を生成する必要があることに注意してください。

これを実現するには、例としてシーケンスを使用します:

FactoryBot.define do factory :story do # story attributes sequence(:title) { |n| "Title#{n}" } # Unique title for every story association :author, factory: :user, first_name: "Jon" endend

また、faker というユニークな値を生成するのに役立つ興味深い gem があります。

Polymorphic Association のデータを生成する

多相関連は少し混乱しやすいかもしれません。 この例で理解が深まれば幸いです。 多相関連を持つ次のクラスがあるとします。

class Profile belongs_to :profileable, polymorphic: trueendclass Account belongs_to :accountable, polymorphic: trueendclass User has_one :profile, as: :profileable has_one :account, as: :accountableend

多相モデルを持つモデルのファクトリーを作成する場合、単に after(:create) ブロックで多相モデルを作成し、多相可能を指定して、ファクトリーが対象とするモデルを指定するだけです。… 以上です!

この記事を読んでいただきありがとうございます。

Railsに関する興味深い記事をもっと読みたい場合は、ぜひニュースレターを購読してください!

同様の話題に興味がありますか? Rspec let vs before、Rspec Setup、FactoryGirl – create vs build vs buldstubbed の各項目について、ぜひご覧ください。

コメントを残す

メールアドレスが公開されることはありません。