Rails accept_nested_attributes_for child não possui pai configurado ao validar

Estou tentando acessar meu modelo pai em meu modelo filho ao validar. Eu encontrei algo sobre uma propriedade inversa no has_one, mas meu Rails 2.3.5 não o reconhece, então ele nunca deve ter entrado no release. Eu não tenho certeza se é exatamente o que eu preciso embora.

Eu quero validar o filho condicionalmente com base em atributos pai. Meu modelo pai já foi criado. Se a criança não tiver sido criada quando eu atualizar_atributos no pai, ela não terá access ao pai. Eu estou querendo saber como eu posso acessar esse pai. Deve ser fácil, algo como parent.build_child define o parent_id do modelo filho, por que ele não está sendo feito ao construir o filho para o accept_nested_attributes_for?

Por exemplo:

class Parent < AR has_one :child accepts_nested_attributes_for :child end class Child  :some_method def some_method return self.parent.some_condition # => undefined method `some_condition' for nil:NilClass end end 

Minha forma é padrão:

      

Com um método de atualização

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

Eu tinha basicamente o mesmo problema com o Rails 3.2. Como sugerido na pergunta, adicionar a opção inverse_of à associação dos pais corrigiu para mim.

Eu tive um problema semelhante: Ruby on Rails – atributos nesteds: como eu access o modelo pai do modelo filho

Foi assim que resolvi isso eventualmente; definindo pai no retorno de chamada

 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 

Você não pode fazer isso porque o filho na memory não conhece o pai ao qual está designado. Só sabe depois de salvar. Por exemplo.

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

Assim, você pode forçar esse comportamento fazendo associações reversas manualmente. Por exemplo

 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 

Se você realmente achar necessário.

PS A razão pela qual não está fazendo isso agora é porque não é muito fácil. Ele precisa ser explicitamente informado sobre como acessar pai / filho em cada caso específico. Uma abordagem abrangente com mapa de identidade teria resolvido isso, mas para a versão mais recente há :inverse_of solução alternativa. Algumas discussões como essa ocorreram em grupos de notícias.

verifique esses sites, talvez eles te ajudem …

Falha na validação da associação de atributos nesteds do Rails

accept_nested_attributes_for validação da associação filho com falha

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

ao que parece, o rails atribuirá parent_id após a validação do filho ser bem-sucedida. (como pai tem um id depois que ele é salvo)

Talvez valha a pena tentar isso:

 child.parent.some_condition 

em vez de self.parent.some_condition … quem sabe …