Rails 3 ActiveRecord :: UnknownAttributeError "atributo desconocido: _destroy" para registros anidados

Digamos que tengo un esquema en el que una caja de manzanas contiene cero o más manzanas. Mientras edito la caja de manzanas en un formulario, quiero enumerar las manzanas y proporcionar una casilla de verificación junto a cada manzana, para eliminarlas cuando se envía el formulario.

No hay nada que vaya mal que yo pueda ver. En mi modelo digo

class AppleCrate < ActiveRecord::Base
  has_many :apples
  accepts_nested_attributes_for :apples, :allow_destroy => true
  ...
end

Tengo el formulario funcionando, por lo que puedo decir. Las casillas de verificación aparecen en el formulario html y cuando el controlador procesa el formulario, cada manzana en la lista tiene un atributo llamado "_destroy" que se establece en "1" o "0" dependiendo de si marqué o no la casilla antes sumisión.

De acuerdo con la API de Rails, cuando configuro _destroy en 1 y guardo, la manzana debe eliminarse. Pero cuando envío el formulario me sale

ActiveRecord::UnknownAttributeError en AppleCrateController#update

atributo desconocido: _destroy

...

"apple_crate"=>{"id"=>"10101", "manzanas"=>{"1"=>{"id"=>"1", "variedad"=>"granny smith", "apple_crate_id"= >"10101", "_destroy"=>"1"}, "2"=>{"id"=>"2", "variedad"=>"fuji", "apple_crate_id"=>"10101", "_destroy "=>"1"}, "3"=>{"id"=>"3", "variedad"=>"macintosh", "apple_crate_id"=>"10101", "_destroy"=>"0"} , ...

y así sucesivamente.

Debo estar perdiendo algo obvio, pero después de varios días de estar dando vueltas, no puedo resolverlo. Puedo hacer todo lo demás con éxito: actualizar, editar, indexar, etc., siempre que deje de lado el atributo :_destroy. ¿Algunas ideas?

(Por si sirve de algo, estoy ejecutando Rails 3.2.2 en Windows).

Actualizado:

Este planteamiento de « es lo que estoy viendo en la documentación. (Consulte la subsección "Uno a muchos".)

Actualizado:

Como se solicita en los comentarios, aquí está la vista:

<%= form_for @apple_crate do |f| %>
  <% @apples = @apple_crate.apples %>  
  <% @apples.each do |apple| %>
    <%= fields_for "apples[]", apple do |apple_fields| %>
      <%= apple_fields.text_field :variety %>
      <%= apple_fields.hidden_field :apple_crate_id %>
      <%= apple_fields.hidden_field :id %>
      <%= apple_fields.check_box :_destroy %>
    <% end %>
  <% end %>
  <%= f.submit "Save" %>
<% end %>

preguntado el 09 de marzo de 12 a las 16:03

de acuerdo a este parece ser que necesitas agregar attr_accessible :_destroy a su modelo AppleCrate -

Gracias por tu comentario. No estoy seguro de por qué sería necesario: _destroy no es un atributo de modelo real. Creo que se supone que debe analizarse durante update_attributes. En cualquier caso, probé lo que sugeriste y recibí el mismo mensaje de error. -

Parece ser que pensé dónde podría haber un error. Adjunte su código de generación de formulario, debe tener apples_attributes en lugar de solo apples en params hash -

Intenté cambiar "manzanas []" en el código de vista anterior a "apple_attributes []", e hice el cambio correspondiente en el código del controlador y obtuve el mismo error. Puedo llamarlo como quieras -- "asdf[]" -- y obtengo el mismo resultado. -

1 Respuestas

Debe generar formularios anidados y formularios con ayudantes de rieles, no lo haga con las manos. Así que creo que ahí es donde está tu error.

Tratar:

<%= form_for @apple_crate do |f| %>
  <%= f.fields_for :apples do |apple_fields| %>
    <%= apple_fields.text_field :variety %>
    <%= apple_fields.hidden_field :apple_crate_id %>
    <%= apple_fields.hidden_field :id %>
    <%= apple_fields.check_box :_destroy %>
  <% end %>
<% end %>

algo como esto, no comprobé si es correcto, pero la idea debería ser lo suficientemente clara

respondido 09 mar '12, 18:03

Esa es la respuesta correcta y coincide más estrechamente con el ejemplo de la API. ¡Gracias! (El problema que estaba teniendo, para ser claro, es que no entendía que _destroy no tiene significado fuera del contexto del AppleCrate principal). Eric de Riel

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.