ruby on rails - rails - Modelos anidados y validación de padres
nested form rails (2)
Esto probablemente funcione para usted, pero tengo la sensación de que hay una respuesta mucho mejor por ahí. Suena como un error para mí.
class Parent
validate :must_have_children
def must_have_children
if children.empty? or children.all? {|child| child.marked_for_destruction? }
errors.add(:base, ''Must have at least one child'')
end
end
end
Tengo dos modelos.
- Parent
tiene_muchos Children
;
- El Parent
accept_nested_attributes_for Children
;
class Parent < ActiveRecord::Base
has_many :children, :dependent => :destroy
accepts_nested_attributes_for :children, :allow_destroy => true
validates :children, :presence => true
end
class Child < ActiveRecord::Base
belongs_to :parent
end
Utilizo la validación para validar la presencia de niños para cada padre, por lo que no puedo guardar el padre sin hijos.
parent = Parent.new :name => "Jose"
parent.save
#=> false
parent.children_attributes = [{:name => "Pedro"}, {:name => "Emmy"}]
parent.save
#=> true
la validación funciona Luego destruiremos a los niños mediante el atributo _destroy
:
parent.children_attributes = {"0" => {:id => 0, :_destroy => true}}
parent.save
#=> true !!!
parent.reload.children
#=> []
entonces puedo destruir a todos los niños a través de formularios anidados y la validación pasará.
En realidad eso sucede porque después de que _delete
secundario de mi padre a través de _delete
, el método children aún devuelve el objeto destruido antes de que lo vuelva a cargar, por lo que se aprueba la validación:
parent.children_attributes = {"0" => {:id => 0, :_destroy => true}}
parent.save
#=> true !!!
parent.children
#=> #<Child id:1 ...> # It''s actually deleted
parent.reload.children
#=> []
¿Es un error?
Cuál es la pregunta. La pregunta es la mejor solución para repararlo. Mi enfoque es agregar el filtro before_destroy a Child
para verificar si es el último. Pero hace que el sistema sea complicado.
No es un error. De acuerdo con la documentación
Valida que los atributos especificados no estén en blanco (como se define por Object # blank?)
y validates :children, :presence => true
es lo mismo. La documentación no dice qué sucede si intenta usarlo en una asociación. Debe usar la validación personalizada usando validate
.
Usando validates_presence_of
on has_many
llamadas de asociación en blank?
en asociación de children
, que es un objeto de la clase Array. Desde el blank?
no se define para una Array
, se dispara method_missing
que está atrapado dentro de Rails. Por lo general, hace lo que quiere pero me parece que falla en Rails 3.1rc y Ruby 1.8.7 de una manera realmente horrible: revierte silenciosamente los cambios de los registros asociados. Me tomó un par de horas descubrir qué está pasando.