Eu preciso consistir a existência de registros "filhos" para poder
efetuar uma exclusão. Se houver "filhos", não posso excluir.
Para isto utilizei o callback "before_destroy", da seguinte forma.
before_destroy :tem_filhos?
Pela documentação, se ":tem_filhos?" retornar "false" o "destroy"
deveria ser abortado e um rollback deveria ser disparado.
Infelizmente não é o que está acontecendo. Cheguei a forçar o retorno
do false (como situação única) e, mesmo assim, o "destroy" no registro
"pai" é executado.
Estou fazendo correto?
Como fazer para evitar que um registro "pai" seja excluído se houver
"filhos"?
> Eu preciso consistir a existência de registros "filhos" para poder
> efetuar uma exclusão. Se houver "filhos", não posso excluir.
> Para isto utilizei o callback "before_destroy", da seguinte forma.
> before_destroy :tem_filhos?
> Pela documentação, se ":tem_filhos?" retornar "false" o "destroy"
> deveria ser abortado e um rollback deveria ser disparado.
> Infelizmente não é o que está acontecendo. Cheguei a forçar o retorno
> do false (como situação única) e, mesmo assim, o "destroy" no registro
> "pai" é executado.
> Estou fazendo correto?
> Como fazer para evitar que um registro "pai" seja excluído se houver
> "filhos"?
>> Eu preciso consistir a existência de registros "filhos" para poder
>> efetuar uma exclusão. Se houver "filhos", não posso excluir.
>> Para isto utilizei o callback "before_destroy", da seguinte forma.
>> before_destroy :tem_filhos?
>> Pela documentação, se ":tem_filhos?" retornar "false" o "destroy"
>> deveria ser abortado e um rollback deveria ser disparado.
>> Infelizmente não é o que está acontecendo. Cheguei a forçar o retorno
>> do false (como situação única) e, mesmo assim, o "destroy" no registro
>> "pai" é executado.
>> Estou fazendo correto?
>> Como fazer para evitar que um registro "pai" seja excluído se houver
>> "filhos"?
No seu modelo você deve fazer um overload do método before_destroy
(isto é, criar um método chamado before_destroy) dentro do seu modelo.
Se esse método retornar falso, aí sim, a ação é cancelada.
> Eu preciso consistir a existência de registros "filhos" para poder
> efetuar uma exclusão. Se houver "filhos", não posso excluir.
> Para isto utilizei o callback "before_destroy", da seguinte forma.
> before_destroy :tem_filhos?
> Pela documentação, se ":tem_filhos?" retornar "false" o "destroy"
> deveria ser abortado e um rollback deveria ser disparado.
> Infelizmente não é o que está acontecendo. Cheguei a forçar o retorno
> do false (como situação única) e, mesmo assim, o "destroy" no registro
> "pai" é executado.
> Estou fazendo correto?
> Como fazer para evitar que um registro "pai" seja excluído se houver
> "filhos"?
1) Tanto a utilização do callback "before_destroy", quanto fazer um overload
do método "before_destroy", funcionam. Isto é, retornando "false" o
"destroy" é abortado.
2) Onde, então, está o problema? Se na declaração do "has_many" for
utilizada a opçao ":dependent => destroy" em relação ao filho - o que,
convenhamos, não faz sentido, pois é justamente o que se quer evitar ;-) -
os registros do filho serão excluídos antes da validação. Isto é, o
"dependent => :destroy" é executado antes do "before_save". Aí, quando o
"before_save" é executado, não há mais registros filhos, pois já foram
excluídos.
3) Mas e se eu quiser usar o ":dependent : => destroy" junto com o
"before_destroy", tem como? Tem. Simplesmente declare o "before_destroy"
ANTES do "has_many". Como está bem descrito na documentação, o Rails executa
os callbacks na ordem em que aparecem.
> No seu modelo você deve fazer um overload do método before_destroy
> (isto é, criar um método chamado before_destroy) dentro do seu modelo.
> Se esse método retornar falso, aí sim, a ação é cancelada.
> > Eu preciso consistir a existência de registros "filhos" para poder
> > efetuar uma exclusão. Se houver "filhos", não posso excluir.
> > Para isto utilizei o callback "before_destroy", da seguinte forma.
> > before_destroy :tem_filhos?
> > Pela documentação, se ":tem_filhos?" retornar "false" o "destroy"
> > deveria ser abortado e um rollback deveria ser disparado.
> > Infelizmente não é o que está acontecendo. Cheguei a forçar o retorno
> > do false (como situação única) e, mesmo assim, o "destroy" no registro
> > "pai" é executado.
> > Estou fazendo correto?
> > Como fazer para evitar que um registro "pai" seja excluído se houver
> > "filhos"?