Cechy mogą być rejestrowane na całym świecie, dzięki czemu można je stosować w każdym innym zakładzie bez użycia FactoryGirl za dziedziczenie:
FactoryGirl.define do
trait :no_author do
after(:build) { |authorable| authorable.author = nil }
end
trait :no_tenant do
tenant nil
end
factory :model do
tenant { build(:tenant) }
end
end
Następnie można po prostu zbudować obiekty tak:
FactoryGirl.build(:model, :no_tenant)
FactoryGirl.build(:model, :no_author)
after
callbacks mogą być również rejestrowane globalnie, ale to oznacza, że są one uruchamiane dla dowolnego obiektu FactoryGirl tworzy, co może powodować niepożądane efekty uboczne:
FactoryGirl.define do
after(:build) do |authorable|
authorable.author = build(:user, tenant: authorable.tenant)
end
factory :model do
tenant { build(:tenant) }
end
factory :other_model
end
FactoryGirl.build(:model) # Happiness!
FactoryGirl.build(:other_model) # undefined method `tenant'
Aby tego uniknąć, można owinąć zwrotnego w cechy, jak to zrobiliśmy w cechy :no_author
, lub użyć fabrycznego dziedziczenia:
FactoryGirl.define do
factory :tenancyable do
trait :no_tenant do
tenant nil
end
factory :authorable do
after(:build) do |authorable|
authorable.author = build(:user, tenant: authorable.tenant)
end
trait :no_author do
after(:build) do |authorable|
authorable.author = nil
end
end
end
end
factory :model, parent: :authorable, class: 'Model' do
tenant { build(:tenant) }
end
factory :other_model
end
Zauważ, że klasa dla potrzeb fabryki model
należy wyraźnie określić tutaj, aby to działało. Możesz teraz budować obiekty:
FactoryGirl.build(:model, :no_author) # Happiness!
FactoryGirl.build(:other_model) # More Happiness!
Przy drugim podejściu cechy i wywołania zwrotne są bardziej ograniczone. Może to w rzeczywistości spowodować mniej niechcianych niespodzianek, gdy masz duży kod z wieloma fabrykami.