2015-12-01 9 views
6

'da paramiklikler içeren başka bir özellikten gelen çağrı özelliğinden yararlanın. Paramları kabul eden ve bir has_many ilişkisi oluşturan oldukça karmaşık bir Factory Girl özellikim var. Bu özelliği, özelliklerin kuruması veya özellikleri fabrikalara aktarırken bir araya getirmeyi kolaylaştırmak için başka bir özelliğin parçası olarak çağırabilirim. Bilmediğim şey, başka bir özellikten ya da bunun yerine ne yapacağımı söylediğimde, paramları bir özelliğe nasıl geçireceğimi bilmem.Factory_girl

örn.

FactoryGirl.define do 
    factory :currency do 
    name Forgery::Currency.description 
    sequence(:short_name) { |sn| "#{Forgery::Currency.code}#{sn}" } 
    symbol '$' 
    end 

    factory :price do 
    full_price { 6000 } 
    discount_price { 3000 } 
    currency 
    subscription 
    end 

    sequence(:base_name) { |sn| "subscription_#{sn}" } 

    factory :product do 
    name { generate(:base_name) } 
    type { "reading" } 
    duration { 14 } 


    trait :reading do 
     type { "reading subscription" } 
    end 

    trait :maths do 
     type { "maths subscription" } 
    end 

    trait :six_month do 
     name { "six_month_" + generate(:base_name) } 
     duration { 183 } 
    end 

    trait :twelve_month do 
     name { "twelve_month_" + generate(:base_name) } 
     duration { 365 } 
    end 

    factory :six_month_reading, traits: [:six_month, :reading] 
    factory :twelve_month_reading, traits: [:twelve_month, :reading] 

    trait :with_price do 
     transient do 
     full_price 6000 
     discount_price 3000 
     short_name 'AUD' 
     end 

     after(:create) do |product, evaluator| 
     currency = Currency.find_by(short_name: evaluator.short_name) || 
        create(:currency, short_name: evaluator.short_name) 
     create_list(
      :price, 
      1, 
      product: product, 
      currency: currency, 
      full_price: evaluator.full_price, 
      discount_price: evaluator.discount_price 
     ) 
     end 
    end 

    trait :with_aud_price do 
     with_price 
    end 

    trait :with_usd_price do 
     with_price short_name: 'USD' 
    end 
    end 
end 

create(:product, :with_aud_price) # works 
create(:product, :with_usd_price) # fails "NoMethodError: undefined method `with_price=' for #<Subscription:0x007f9b4f3abf50>" 

# What I really want to do 
factory :postage, parent: :product do 
    with_aud_price full_price: 795 
    with_usd_price full_price 700 
end 

cevap

6

:with_price özellik yani bunun yerine siz kuruyorsunuz diğer özellikleri ayrı bir satırda olması gerekir:

trait :with_usd_price do 
    with_price short_name: 'USD' 
end 

bunu kullanın: Ben

trait :with_usd_price do 
    with_price 
    short_name: 'USD' 
end 
+0

Bunun neden işe yaradığını anlamıyorum, ama çok memnunum. – jim

+0

Bir tahminde, B özelliği içinde, A özelliği içinde, A özelliği, A özelliği, A özelliği alt sınıfını çizer. Bu, birden fazla kalıtımın desteklendiğini ve her iki özellikinizin de aynı geçici özellikleri vb. Tanımlarsa ne olacağını bilen anlamına gelir. İlk veya sonuncusunun sadece önceliği olduğunu tahmin et. Fabrikalar için kullanılan “ebeveyn:: foo” sözdizimi gibi bir şeyden ziyade bir yöntem çağrısı gibi kalıtımı tanımlamak biraz şaşırtıcı görünüyor. – jim

+0

Tamam. Buna daha fazla baktım, olduğu kadar iyi, ama hala örnekte OP'deki kod örneğinin en altındaki örneği yapamam. Bu formda denerseniz, FactoryGirl :: AttributeDefinitionError: Önceden tanımlanmış öznitelik olsun: full_price. Hmm ... Geçici özellikler için dizilerle çalışmayı başarabilirim. – jim

0

factory_bot 4.8.2 üzerinde m ve aşağıdakiler benim için şu anlama gelir:

trait :with_usd_price do 
    with_price 
    short_name 'USD' 
end 
İlgili konular