Eu tenho alguns modelos que têm retornos de chamada after_save. Normalmente, isso é bom, mas em algumas situações, como ao criar dados de desenvolvimento, quero salvar os modelos sem que os retornos de chamada sejam executados. Existe uma maneira simples de fazer isso? Algo parecido com ...
Person#save( :run_callbacks => false )
ou
Person#save_without_callbacks
Procurei nos documentos do Rails e não encontrei nada. No entanto, na minha experiência, os documentos do Rails nem sempre contam toda a história.
ATUALIZAR
Encontrei uma postagem no blog que explica como você pode remover retornos de chamada de um modelo como este:
Foo.after_save.clear
Não consegui encontrar onde esse método está documentado, mas parece funcionar.
Foo.after_save.clear
removeria retornos de chamada para o modelo inteiro? E então, como você propõe restaurá-los?Respostas:
Esta solução é apenas o Rails 2.
Acabei de investigar isso e acho que tenho uma solução. Existem dois métodos particulares do ActiveRecord que você pode usar:
Você precisará usar send para chamar esses métodos. exemplos:
Definitivamente, isso é algo que você realmente deseja usar no console ou durante alguns testes aleatórios. Espero que isto ajude!
fonte
Use
update_column
(Rails> = v3.1) ouupdate_columns
(Rails> = 4.0) para ignorar retornos de chamada e validações. Também com esses métodos, nãoupdated_at
é atualizado.http://api.rubyonrails.org/classes/ActiveRecord/Persistence.html#method-i-update_column
# 2: Ignorando retornos de chamada que também funcionam ao criar um objeto
fonte
:create_without_callbacks
:( Como posso executar algo semelhante a isso (Trabalhou em Rails2, removido em Rails3)?.@person
seja uma variável em um controlador em algum lugar, essa solução significa que as pessoas que estão lendo sua classe de modelo não serão capazes de entender os retornos de chamada. Eles verãoafter_create :something_cool
e pensarão "ótimo, algo legal acontece após a criação!". Para realmente entender sua classe de modelo, eles terão que passar por todos os seus controladores, procurando todos os pequenos lugares onde você decidiu injetar lógica. Eu não gosto disso> o <;;skip_callback ..., if: :skip_some_callbacks
porafter_create ..., unless: :skip_some_callbacks
para executar isso corretamente com after_create.Atualizada:
A solução de @Vikrant Chaudhary parece melhor:
Minha resposta original:
consulte este link: Como pular retornos de chamada do ActiveRecord?
no Rails3,
suponha que temos uma definição de classe:
Abordagem 1:
Abordagem 2: Quando você quiser ignorá-los em seus arquivos rspec ou qualquer outra coisa, tente o seguinte:
NOTA: quando isso for feito, se você não estiver no ambiente rspec, deverá redefinir os retornos de chamada:
funciona bem para mim nos trilhos 3.0.5
fonte
trilhos 3:
fonte
reset_callbacks
não é:after_save
, mas sim:save
. apidock.com/rails/v3.0.9/ActiveSupport/Callbacks/ClassMethods/…Se o objetivo é simplesmente inserir um registro sem retornos de chamada ou validações, e você gostaria de fazê-lo sem recorrer a gemas adicionais, adicionando verificações condicionais, usando RAW SQL ou futzing com o código existente, considere usar uma "sombra" objeto "apontando para sua tabela db existente. Igual a:
Isso funciona com todas as versões do Rails, é seguro para threads e elimina completamente todas as validações e retornos de chamada sem modificações no código existente. Você pode simplesmente lançar essa declaração de classe antes da importação real e deve estar pronto. Lembre-se de usar sua nova classe para inserir o objeto, como:
fonte
Você pode tentar algo assim no seu modelo de pessoa:
EDIT: after_save não é um símbolo, mas é pelo menos a milésima vez que tentei torná-lo um.
fonte
send
. KOODOSVocê pode usar
update_columns
:fonte
A única maneira de impedir todos os retornos de chamada after_save é fazer com que o primeiro retorne falso.
Talvez você possa tentar algo como (não testado):
fonte
Parece que uma maneira de lidar com isso no Rails 2.3 (desde que o update_without_callbacks se foi, etc.) seria usar o update_all, que é um dos métodos que ignora os retornos de chamada conforme a seção 12 do Guia do Rails para validações e retornos de chamada .
Além disso, observe que, se você estiver fazendo algo em seu retorno de chamada posterior, faça um cálculo com base em muitas associações (por exemplo, um has_many assoc, em que você também aceita accept_nested_attributes_for), será necessário recarregar a associação, caso faça parte do salvamento , um de seus membros foi excluído.
fonte
https://gist.github.com/576546
basta despejar esse patch de macaco em config / initializers / skip_callbacks.rb
então
Project.skip_callbacks { @project.save }
ou semelhante.
todo o crédito ao autor
fonte
A maioria das
up-voted
respostas pode parecer confusa em alguns casos.Você pode usar apenas uma
if
verificação simples se desejar pular um retorno de chamada, assim:fonte
Uma solução que deve funcionar em todas as versões do Rails sem o uso de uma gema ou plugin é simplesmente emitir instruções de atualização diretamente. por exemplo
Isso pode (ou não) ser uma opção, dependendo da complexidade da sua atualização. Isso funciona bem para ex bandeiras de atualização em um registro de dentro de um retorno de chamada after_save (sem retriggering o callback).
fonte
#{...}
.fonte
Nenhum desses pontos para o
without_callbacks
plugin que apenas faz o que você precisa ...http://github.com/cjbottaro/without_callbacks funciona com o Rails 2.x
fonte
Eu escrevi um plugin que implementa update_without_callbacks no Rails 3:
http://github.com/dball/skip_activerecord_callbacks
A solução certa, eu acho, é reescrever seus modelos para evitar retornos de chamada em primeiro lugar, mas se isso for impraticável no curto prazo, esse plug-in pode ajudar.
fonte
Se você estiver usando o Rails 2. Você pode usar a consulta SQL para atualizar sua coluna sem executar retornos de chamada e validações.
Eu acho que deve funcionar em qualquer versão de trilhos.
fonte
Quando preciso ter controle total sobre o retorno de chamada, crio outro atributo que é usado como uma opção. Simples e eficaz:
Modelo:
Teste:
fonte
Para criar dados de teste no Rails, você usa este hack:
https://coderwall.com/p/y3yp2q/edit
fonte
Você pode usar a joia de salvamento furtivo: https://rubygems.org/gems/sneaky-save .
Observe que isso não pode ajudar a salvar associações sem validações. Ele gera o erro 'created_at não pode ser nulo', pois insere diretamente a consulta sql, diferente de um modelo. Para implementar isso, precisamos atualizar todas as colunas geradas automaticamente do db.
fonte
Eu precisava de uma solução para o Rails 4, então vim com isso:
app / modelos / preocupações / save_without_callbacks.rb
em qualquer modelo:
então você pode:
ou
fonte
Por que você gostaria de fazer isso no desenvolvimento? Certamente, isso significa que você está construindo seu aplicativo com dados inválidos e, como tal, se comportará de maneira estranha e não como o esperado na produção.
Se você deseja preencher seu banco de dados de desenvolvimento com dados, uma abordagem melhor seria criar uma tarefa de rake que usasse a gema mais falsa para criar dados válidos e importá-los para o banco de dados, criando tantos ou poucos registros quanto desejar, mas se você estiver preparado inclinado e com um bom motivo, acho que update_without_callbacks e create_without_callbacks funcionarão bem, mas quando você estiver tentando dobrar os trilhos à sua vontade, pergunte a si mesmo que tem um bom motivo e se o que está fazendo é realmente uma boa ideia.
fonte
Uma opção é ter um modelo separado para essas manipulações, usando a mesma tabela:
(A mesma abordagem pode facilitar as coisas para ignorar validações)
Stephan
fonte
Outra maneira seria usar ganchos de validação em vez de retornos de chamada. Por exemplo:
Dessa forma, você pode obter o do_something por padrão, mas pode substituí-lo facilmente por:
fonte
Algo que deve funcionar com todas as versões
ActiveRecord
sem depender de opções ou métodos de registro de ativos que possam ou não existir.TLDR: use um "modelo de registro de ativo diferente" na mesma tabela
fonte
Para retornos de chamada personalizados, use um
attr_accessor
e umunless
no retorno de chamada.Defina seu modelo da seguinte maneira:
E então se você precisa salvar o registro sem bater os
after_save
retornos de chamada que você definiu, defina oskip_after_save_callbacks
atributo virtual paratrue
.fonte
Não é a maneira mais limpa, mas você pode agrupar o código de retorno de chamada em uma condição que verifique o ambiente do Rails.
fonte