Pytanie Jak skonfigurować fabrykę w FactoryGirl z has_many association


Czy ktoś może mi powiedzieć, że jeśli chodzi o konfigurację w niewłaściwy sposób?

Mam następujące modele, które mają asocjacje has_many.through:

class Listing < ActiveRecord::Base
  attr_accessible ... 

  has_many :listing_features
  has_many :features, :through => :listing_features

  validates_presence_of ...
  ...  
end


class Feature < ActiveRecord::Base
  attr_accessible ...

  validates_presence_of ...
  validates_uniqueness_of ...

  has_many :listing_features
  has_many :listings, :through => :listing_features
end


class ListingFeature < ActiveRecord::Base
  attr_accessible :feature_id, :listing_id

  belongs_to :feature  
  belongs_to :listing
end

Używam Rails 3.1.rc4, FactoryGirl 2.0.2, factory_girl_rails 1.1.0 i rspec. Oto moje podstawowe sprawdzanie poprawności rspec rspec dla :listing fabryka:

it "creates a valid listing from factory" do
  Factory(:listing).should be_valid
end

Oto Factory (: listing)

FactoryGirl.define do
  factory :listing do
    headline    'headline'
    home_desc   'this is the home description'
    association :user, :factory => :user
    association :layout, :factory => :layout
    association :features, :factory => :feature
  end
end

The :listing_feature i :feature fabryki są podobnie skonfigurowane.
Jeśli association :features linia jest zakomentowana, a następnie wszystkie moje testy mijają.
Kiedy to jest

association :features, :factory => :feature

komunikat o błędzie jest undefined method 'each' for #<Feature>  które wydawało mi się sensowne, ponieważ ponieważ listing.features zwraca tablicę. Więc zmieniłem to na

association :features, [:factory => :feature]

a błąd, który teraz otrzymuję, jest ArgumentError: Not registered: features  Czy nie jest rozsądne wytwarzanie obiektów fabrycznych w ten sposób, czy też tego, czego mi brakuje? Dziękuję bardzo za wszelkie dane wejściowe!


76
2017-08-05 22:30


pochodzenie




Odpowiedzi:


Tworzenie takich powiązań wymaga użycia wywołań FactoryGirl.

Doskonały zestaw przykładów można znaleźć tutaj.

http://robots.thoughtbot.com/post/254496652/aint-no-calla-back-girl

Aby przynieść to do domu na twój przykład.

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

51
2017-10-11 23:04



czy w końcu użyłeś asocjacji: features, [: factory =>: feature]? - davidtingsu


Możesz też użyć bloku i pominąć association słowo kluczowe. Dzięki temu można budować obiekty bez zapisywania w bazie danych (w przeciwnym razie skojarzenie has_many spowoduje zapisanie rekordów do bazy danych, nawet jeśli używa się build funkcja zamiast create).

FactoryGirl.define do
  factory :listing_with_features, :parent => :listing do |listing|
    features { build_list :feature, 3 }
  end
end

85
2017-09-25 17:11



To kocie miauczenie. Zdolność do obu build i create sprawia, że ​​jest to najbardziej uniwersalny wzór. Następnie użyj tej niestandardowej strategii budowania FG gist.github.com/Bartuz/74ee5834a36803d712b7 do post nested_attributes_for podczas testowania działań kontrolera, które accepts_nested_attributes_for - Chris Beck
przegłosowane, znacznie bardziej czytelne i wszechstronne niż przyjęta odpowiedź IMO - m_x


Wypróbowałem kilka różnych podejść i to jest ten, który zadziałał najbardziej niezawodnie (dostosowany do twojego przypadku)

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

20
2017-11-15 03:51





Możesz użyć trait:

FactoryGirl.define do
  factory :listing do
    ...

    trait :with_features do
      features { build_list :feature, 3 }
    end
  end
end

Z callback, jeśli potrzebujesz tworzenia bazy danych:

...

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

Użyj w specyfikacji tak:

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

Spowoduje to usunięcie duplikacji w fabrykach i stanie się bardziej przydatny do ponownego użycia.

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


13
2018-01-23 18:39





Oto, jak ustawić moje:

# 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

A następnie w swoich testach możesz:

@preference_set = FactoryGirl.create(:preference_set_with_preferences)

Nadzieja, która pomaga.


0
2017-09-08 16:20