2012-01-13 9 views
22

Próbuję uzyskać informacje o skojarzeniach ActiveRecord, ale uderzyłem nieco w mur i niezależnie od tego, jak bardzo przejrzałem dokumentację ActiveRecord, nie mogę stwierdzić jak rozwiązać mój problem.Tworzenie lub aktualizowanie asocjacji has_one ActiveRecord

Mam dwie klasy:

Property -> has_one :contract 
Contract -> belongs_to :property 

w mojej klasie kontraktu, mam metodę create_or_update_from_xml

Najpierw upewnij się, właściwość istnieje w pytanie.

property_unique_id = xml_node.css('property_id').text 
     property = Property.find_by_unique_id(property_unique_id) 
     next unless property 

I to gdzie ja utknąć, mam hash atrybutów dla umowy, a to, co chcę zrobić, to coś takiego:

if property.contract.nil? 
    # create a new one and populate it with attributes 
else 
    # use the existing one and update it with attributes 

wiem jak bym go o to jeśli był to surowy kod SQL, ale nie mogę się skupić na podejściu ActiveRecord.

Wszelkie sugestie dotyczące tego bloku drogowego będą niezwykle cenne.

Z góry dziękuję.

Odpowiedz

33
if property.contract.nil? 
    property.create_contract(some_attributes) 
else 
    property.contract.update_attributes(some_attributes) 
end 

Powinien załatwić sprawę. Kiedy masz skojarzenie has_one lub belongs_to, otrzymujesz metody build_foo i create_foo (które są podobne do Foo.new i Foo.create). Jeśli powiązanie już istnieje, to property.contract jest po prostu normalnym aktywnym obiektem rekordowym.

+0

Dzięki za to, roboty doskonale. –

+0

może użyć pustego? – Dan

7
Property.all.each do |f| 
    c = Contract.find_or_initialize_by(property_id: f.id) 
    c.update(some_attributes) 
end 

Nie wiem, czy jest to najlepsze rozwiązanie, ale dla mnie to bardziej zwięźle

9

Kolejny sposób to zrobić przy użyciu Ruby OR-Equal sztuczkę

property.contract ||= property.build_contract 
property.contract.update_attributes(some_attributes) 
+2

Po przypisaniu obiektu do asocjacji has_one obiekt ten jest automatycznie zapisywany, co może spowodować przerwanie sprawdzania poprawności. http://guides.rubyonrails.org/association_basics.html#has-one-association-reference użyj właściwości property.build_contract, chyba że zamiast właściwości property.contract. –

+0

To jest najlepsza odpowiedź, powinna być zaakceptowana. – ZedTuX

Powiązane problemy