2010-02-09 6 views
9

Estoy tratando de acceder a mi modelo principal en mi modelo hijo al validar. Encontré algo sobre una propiedad inversa en el has_one, pero mi Rails 2.3.5 no lo reconoce, por lo que nunca debe haber estado en el lanzamiento. No estoy seguro si es exactamente lo que necesito sin embargo.Rails accepts_nested_attributes_for child no tiene conjunto primario al validar

Quiero validar el hijo de forma condicional en función de los atributos principales. Mi modelo Parent ya ha sido creado. Si el hijo no se ha creado cuando actualizo los atributos en el padre, entonces no tiene acceso al padre. Me pregunto cómo puedo acceder a este padre. Es debería ser ser fácil, algo así como parent.build_child establece el parent_id del modelo hijo, ¿por qué no lo está haciendo cuando construye el hijo para accept_nested_attributes_for?

Por ejemplo:

class Parent < AR 
    has_one :child 
    accepts_nested_attributes_for :child 
end 
class Child < AR 
    belongs_to :parent 
    validates_presence_of :name, :if => :some_method 

    def some_method 
    return self.parent.some_condition # => undefined method `some_condition' for nil:NilClass 
    end 
end 

Mi forma es estándar:

<% form_for @parent do |f| %> 
    <% f.fields_for :child do |c| %> 
    <%= c.name %> 
    <% end %> 
<% end %> 

Con un método de actualización

def update 
    @parent = Parent.find(params[:id]) 
    @parent.update_attributes(params[:parent]) # => this is where my child validations take place 
end 

Respuesta

0

verificación de estos sitios, tal vez van a ayudar ...

Rails Nested Attributes Association Validation Failing

accepts_nested_attributes_for child association validation failing

http://ryandaigle.com/articles/2009/2/1/what-s-new-in-edge-rails-nested-attributes

parece, rieles asignará parent_id después de la validación niño tiene éxito. (como los padres tiene un id vez guardada)

tal vez vale la pena probar esto:

child.parent.some_condition 

en lugar de self.parent.some_condition ... quien sabe ...

7

Usted no puede hacer esto porque el niño en memoria no sabe que el padre está asignado. Solo lo sabe después de guardar. Por ejemplo.

child = parent.build_child 
parent.child # => child 
child.parent # => nil 

# BUT 
child.parent = parent 
child.parent # => parent 
parent.child # => child 

Así que puede forzar este comportamiento haciendo la asociación inversa manualmente. Por ejemplo

def child_with_inverse_assignment=(child) 
    child.parent = self 
    self.child_without_inverse_assignment = child 
end 

def build_child_with_inverse_assignment(*args) 
    build_child_without_inverse_assignment(*args) 
    child.parent = self 
    child 
end 

def create_child_with_inverse_assignment(*args) 
    create_child_without_inverse_assignment(*args) 
    child.parent = self 
    child 
end 

alias_method_chain :"child=", :inverse_assignment 
alias_method_chain :build_child, :inverse_assignment 
alias_method_chain :create_child, :inverse_assignment 

Si realmente lo considera necesario.

P.S. La razón por la que no lo está haciendo ahora es porque no es demasiado fácil. Se debe indicar explícitamente cómo acceder al padre/hijo en cada caso particular. Un enfoque integral con el mapa de identidad lo habría resuelto, pero para la versión más reciente hay :inverse_of solución alternativa. Algunas discusiones como this one tuvieron lugar en grupos de noticias.

8

que tenía un problema similar: Ruby on Rails - nested attributes: How do I access the parent model from child model

Así es como lo resolví con el tiempo; mediante el establecimiento de los padres en la devolución de llamada

class Parent < AR 
    has_one :child, :before_add => :set_nest 
    accepts_nested_attributes_for :child 

private 
    def set_nest(child) 
    child.parent ||= self 
    end 
end 
+0

Tuve el mismo error que el op, pero cuando probé este método, obtuve "Claves desconocidas: before_add"? – Kvass

8

que tenía básicamente el mismo problema con Rails 3.2.Como se sugirió en la pregunta, al agregar la opción inverse_of a la asociación de padres, se corrigió por mí.

Cuestiones relacionadas