Dapatkah seseorang memberi tahu saya jika saya melakukan penyiapan dengan cara yang salah?
Saya memiliki model berikut yang memiliki asosiasi 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
Saya menggunakan Rails 3.1.rc4, FactoryGirl 2.0.2, factory_girl_rails 1.1.0, dan rspec. Berikut adalah pemeriksaan kewarasan rspec rspec dasar saya untuk :listing
pabrik:
it "creates a valid listing from factory" do
Factory(:listing).should be_valid
end
Berikut adalah Pabrik (: daftar)
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
Pabrik :listing_feature
dan :feature
pabriknya memiliki pengaturan yang sama.
Jika association :features
baris tersebut diberi komentar, maka semua tes saya lulus.
Saat itu
association :features, :factory => :feature
pesan kesalahan
undefined method 'each' for #<Feature>
yang menurut saya masuk akal bagi saya karena karena listing.features
mengembalikan array. Jadi saya mengubahnya menjadi
association :features, [:factory => :feature]
dan kesalahan yang saya dapatkan sekarang adalah ArgumentError: Not registered: features
Apakah tidak masuk akal untuk membuat objek pabrik dengan cara ini, atau apa yang saya lewatkan? Terima kasih banyak atas semua masukannya!
Sebagai alternatif, Anda dapat menggunakan satu blok dan melewatkan
association
kata kunci. Hal ini memungkinkan untuk membangun objek tanpa menyimpan ke database (jika tidak, asosiasi has_many akan menyimpan record Anda ke db, bahkan jika Anda menggunakanbuild
fungsi sebagai ganticreate
).FactoryGirl.define do factory :listing_with_features, :parent => :listing do |listing| features { build_list :feature, 3 } end end
sumber
build
dancreate
menjadikannya pola paling serbaguna. Kemudian gunakan FG kustom ini strategi membangun gist.github.com/Bartuz/74ee5834a36803d712b7 untukpost nested_attributes_for
saat pengujian tindakan controller yangaccepts_nested_attributes_for
association
kata kunci menggunakan strategi build yang sama untuk induk dan turunan . Jadi, itu bisa membangun objek tanpa menyimpan ke database.Anda bisa menggunakan
trait
:FactoryGirl.define do factory :listing do ... trait :with_features do features { build_list :feature, 3 } end end end
Dengan
callback
, jika Anda membutuhkan pembuatan DB:... trait :with_features do after(:create) do |listing| create_list(:feature, 3, listing: listing) end end
Gunakan dalam spesifikasi Anda seperti ini:
let(:listing) { create(:listing, :with_features) }
Ini akan menghapus duplikasi di pabrik Anda dan menjadi lebih dapat digunakan kembali.
https://robots.thoughtbot.com/remove-duplication-with-factorygirls-traits
sumber
Saya mencoba beberapa pendekatan berbeda dan ini adalah pendekatan yang paling andal untuk saya (disesuaikan dengan kasus Anda)
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
sumber
Inilah cara saya menyiapkan milik saya:
# 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
Dan kemudian dalam pengujian Anda, Anda dapat melakukan:
@preference_set = FactoryGirl.create(:preference_set_with_preferences)
Semoga membantu.
sumber