How to set up factory in FactoryGirl with has_many association

前端 未结 5 759
深忆病人
深忆病人 2020-12-07 12:54

Can someone tell me if I\'m just going about the setup the wrong way?

I have the following models that have has_many.through associations:

class List         


        
相关标签:
5条回答
  • 2020-12-07 13:34

    I tried a few different approaches and this is the one that worked most reliably for me (adapted to your case)

    FactoryGirl.define do
      factory :user do
        # some details
      end
    
      factory :layout do
        # some details
      end
    
      factory :feature do
        # some details
      end
    
      factory :listing do
        headline    'headline'
        home_desc   'this is the home description'
        association :user, factory: :user
        association :layout, factory: :layout
        after(:create) do |liztng|
          FactoryGirl.create_list(:feature, 1, listing: liztng)
        end
      end
    end
    
    0 讨论(0)
  • 2020-12-07 13:38

    Creating these kinds of associations requires using FactoryGirl's callbacks.

    A perfect set of examples can be found here.

    https://thoughtbot.com/blog/aint-no-calla-back-girl

    To bring it home to your example.

    Factory.define :listing_with_features, :parent => :listing do |listing|
      listing.after_create { |l| Factory(:feature, :listing => l)  }
      #or some for loop to generate X features
    end
    
    0 讨论(0)
  • 2020-12-07 13:42

    You could use trait:

    FactoryGirl.define do
      factory :listing do
        ...
    
        trait :with_features do
          features { build_list :feature, 3 }
        end
      end
    end
    

    With callback, if you need DB creation:

    ...
    
    trait :with_features do
      after(:create) do |listing|
        create_list(:feature, 3, listing: listing)
      end
    end
    

    Use in your specs like this:

    let(:listing) { create(:listing, :with_features) }
    

    This will remove duplication in your factories and be more reusable.

    https://robots.thoughtbot.com/remove-duplication-with-factorygirls-traits

    0 讨论(0)
  • 2020-12-07 13:47

    Alternatively, you can use a block and skip the association keyword. This makes it possible to build objects without saving to the database (otherwise, a has_many association will save your records to the db, even if you use the build function instead of create).

    FactoryGirl.define do
      factory :listing_with_features, :parent => :listing do |listing|
        features { build_list :feature, 3 }
      end
    end
    
    0 讨论(0)
  • 2020-12-07 13:55

    Here is how I set mine up:

    # Model 1 PreferenceSet
    class PreferenceSet < ActiveRecord::Base
      belongs_to :user
      has_many :preferences, dependent: :destroy
    end
    
    #Model 2 Preference
    
    class Preference < ActiveRecord::Base    
      belongs_to :preference_set
    end
    
    
    
    # factories/preference_set.rb
    
    FactoryGirl.define do
      factory :preference_set do
        user factory: :user
        filter_name "market, filter_structure"
    
        factory :preference_set_with_preferences do
          after(:create) do |preference|
            create(:preference, preference_set: preference)
            create(:filter_structure_preference, preference_set: preference)
          end
        end
      end
    
    end
    
    # factories/preference.rb
    
    FactoryGirl.define do
      factory :preference do |p|
        filter_name "market"
        filter_value "12"
      end
    
      factory :filter_structure_preference, parent: :preference do
        filter_name "structure"
        filter_value "7"
      end
    end
    

    And then in your tests you can do:

    @preference_set = FactoryGirl.create(:preference_set_with_preferences)
    

    Hope that helps.

    0 讨论(0)
提交回复
热议问题