2012-01-13 11 views
22

He estado tratando de entender las asociaciones ActiveRecord, pero he golpeado un poco una pared de ladrillo, y no importa cuánto revise la documentación ActiveRecord, no puedo resolverlo cómo resolver mi problemaCreando o actualizando una asociación has_one ActiveRecord

Tengo dos clases:

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

En mi clase de contrato, tengo un método para create_or_update_from_xml

Primera puedo comprobar para asegurarse de que la propiedad en cuestión existe.

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

Y aquí es donde se queda bloqueado, tengo un hash de atributos para el contrato, y lo que yo quiero hacer es algo como:

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

Yo sé cómo iba a ir sobre ella si era SQL en bruto, pero no puedo entender el enfoque de ActiveRecord.

Cualquier sugerencia más allá de este bloque de carreteras sería muy apreciada.

Gracias de antemano.

Respuesta

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

Debería hacer el truco. Cuando tienes una asociación has_one o belongs_to, obtienes los métodos build_foo y create_foo (que son como Foo.new y Foo.create). Si la asociación ya existe, entonces property.contract es básicamente un objeto de registro activo normal.

+0

Gracias por eso, las obras perfectamente. –

+0

¿tal vez usar en blanco? – Dan

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

No sé si esta es la mejor solución, pero para mí es más sucintamente

9

Sólo otra manera de hacerlo utilizando rubí OR-Equal truco

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

Cuando asigna un objeto a una asociación has_one, ese objeto se guarda automáticamente, lo que puede romper las validaciones. http://guides.rubyonrails.org/association_basics.html#has-one-association-reference use property.build_contract a menos que property.contract en su lugar. –

+0

Esta es la mejor respuesta, debe ser aceptada. – ZedTuX

Cuestiones relacionadas