2012-02-08 4 views
3

Вот ситуация.рубин на рельсах, factory_girl, validates_presence_of и полиморфные ассоциации

Gems: рельсы 3.2, factory_girl 2.5.1

class House 
    has_one :address, :as => :addressable 
    validates :address, :presence => true 
    accepts_nested_attributes_for :address 
end 

class Address 
    attr_accessor :nested 
    belongs_to :addressable, :polymorhic => true 
    validates :addressable, :presence => true, :unless => :nested 
end 

Как это работает.

<%= form_for @house do |f| %> 
    <%= f.label :name %> 
    <%= f.text_field :name %> 
    <%= f.fields_for :address do |a| %> 
    <%= a.hidden_field :nested %> 
    <%= a.label :street_address %> 
    <%= a.text_field :street_address %> 

Каков правильный способ определения фабрики?

# does not work 
Factory.define :house do |h| 
    h.association :address 
end 

# does not work 
Factory.define :house do |h| 
    h.after_build do |record| 
    Factory.build(:address, :addressable => record, :nested => '') 
end 
end 

# does not work 
Factory.define :house do |h| 
    h.after_build do |record| 
    Factory.create(:address, :addressable => record, :nested => '') 
    end 
end 

Так в основном, «трюк», который позволяет accepts_nested_attributes_for: адрес, чтобы обойти валидации и создать обе запись одновременно не работает в factory_girl. В настоящее время этот уродливый беспорядок - единственное решение.

home = House.new 
home.name = 'On the prairie' 
home.address_attributes = Factory.attributes_for(:address, :nested => '') 
home.save 

UPDATE Решение:

Factory.define :house do |h| 
    h.after_build do |record| 
    record.address = Factory.build(:address, :addressable => record) 
    end 
end 
+0

Какую версию FactoryGirl вы используете? Это Rails3? –

+0

Спасибо, добавили их – efoo

+0

Возможный дубликат [FactoryGirl и полиморфных ассоциаций] (http://stackoverflow.com/questions/7747945/factorygirl-and-polymorphic-associations) – Thilo

ответ

3

Ваша вторая попытка FactoryGirl близко, но вы должны сделать что-то с этим построен адрес.

FactoryGirl.define do 

    factory :house do 
    after_build do |house| 
     house.address = Factory.build(:address) 
    end 
    end 

end 
+0

Awesome. Я считаю, что это нужно вложенное. – efoo

+0

Несомненно, вы можете передать любые атрибуты, которые хотите, чтобы ваш адрес имел в качестве второго аргумента Factory.build. –

+0

Правильно, я просто хотел сделать этот конкретный пример работы. – efoo