No rails, como posso descobrir o que causou a falha de um .save (), além dos erros de validação?

91

Eu tenho um modelo ActiveRecord que está retornando truede valid?(e .errors está vazio), mas está retornando falsede save(). Se a instância do modelo for válida, como posso descobrir o que está causando a falha no salvamento?

kdt
fonte
7
Tive esse problema algumas semanas atrás. Algumas refatorações deixaram uma função before_save retornando false o tempo todo, o que faz com que o salvamento falhe.
Jeff Paquette
1
@Jeff - obrigado, descobriu-se que havia um método: before_save retornando false. Como você descobriu? Foi apenas inspeção de código?
kdt
Era uma inspeção de código e fazer diferenças em relação ao controle de versão.
Jeff Paquette

Respostas:

48

Verifique todas as suas chamadas de retorno.

Eu tive um problema como este onde eu tinha um método "after_validate" que estava falhando depois que eu fiz várias alterações no modelo. O modelo era válido, mas o "after_validate" estava retornando falso, então se eu o usei model.validdisse verdadeiro, mas se eu salvei, ele me deu erros de validação (passado pelo callback after_validate). Foi estranho.

Observe o rastreamento do aplicativo e você poderá ver qual linha de código está gerando a exceção.

Andrew
fonte
2
De acordo com o comentário de Jeff, o problema acabou sendo um retorno de chamada before_save retornando false.
kdt
3
@kdt - esse era exatamente o meu problema. Eu não tinha pensado nisso porque before_save tinha como objetivo apenas definir uma propriedade, mas como estava definindo um valor falso, isso foi retornado implicitamente e fez o salvamento falhar silenciosamente. Pelo lado bom, agora tenho a opção de corrigir esse código adicionando a linha "Hey! That's MY fake leg!" # Believe it or not, this is important. Não que eu fosse fazer isso. ;)
Nathan Long
2
Uma boa maneira de garantir um verdadeiro valor de retorno étrue.tap { do_something }
Nathan Long
uau, que questão obscura. Nunca teria suposições de que um retorno de chamada retornando false teria parado de salvar. Alguém poderia me indicar os documentos sobre isso? Obrigado por apontar isso!
Andy
114

Tente usar a versão bang save!(com um ponto de exclamação no final) e inspecione o erro resultante.

Andy Lindeman
fonte
4
Salve ! está apenas lançando um RecordNotSaved (quando imprimo o .message da exceção, acabo de obter o nome da classe de exceção). Há algum lugar onde eu deva procurar mais detalhes?
kdt
1
Se você estiver no modo de desenvolvimento Rails, ele deve imprimir uma descrição completa do erro com rastreamento de pilha. Dê uma olhada lá em busca de pistas e / ou poste aqui.
Andy Lindeman
1
Eu uso o console, carrego o objeto (por exemplo, o = Object.find #id) e faço o.save! como diz a resposta. Ele imprime por que não está salvando.
pduey
1
Para sua informação, pagar save!pode aumentar ActiveRecord::RecordInvalid(já que executa validações) ou ActiveRecord::RecordNotSavedentão é isso que você deseja resgatar.
Dennis
2
+1 porque esta é a resposta menos insatisfatória para a questão fundamental de como diagnosticar .savefalhas que não são devidas à validação. A qualificação "menos insatisfatória" refere-se ao Rails, não a esta resposta.
Chuck Batson de
108

Se @user.save(por exemplo) retornar false, execute-o para obter todos os erros:

@user.errors.full_messages
Sam Alex
fonte
12
Como mencionei na pergunta, .válido? é verdadeiro - ou seja, não há erros de validação. Eu verifiquei se .errors está retornando uma lista vazia também (eu atualizei a pergunta para apontar isso)
kdt
3

Sim, eu corrigi esse problema certificando-me de retornar true em todos os meus before_ * callbacks e começar a funcionar :)

Verificação de lápis
fonte
-1

O problema que tive foi que me esqueci de adicionar a validação ao modelo.

class ContactGroup < ActiveRecord::Base
  validates_presence_of :name
end
Ian Vaughan
fonte