Le #new_record? La fonction détermine si un enregistrement a été sauvegardé. Mais c'est toujours faux dans le after_save
crochet. Existe-t-il un moyen de déterminer si l'enregistrement est un enregistrement nouvellement créé ou un ancien à partir de la mise à jour?
J'espère ne pas utiliser un autre rappel tel que before_create
définir un indicateur dans le modèle ou exiger une autre requête dans la base de données.
Tout conseil est apprécié.
Edit: Nécessité de déterminer dans after_save
crochet, et pour mon cas particulier d'utilisation, il n'y a pas updated_at
ou updated_on
horodatage
ruby-on-rails
activerecord
activemodel
Aaron Qian
la source
la source
Réponses:
Je cherchais à l'utiliser pour un
after_save
rappel.Une solution plus simple consiste à utiliser
id_changed?
(car cela ne changera pasupdate
) ou mêmecreated_at_changed?
si des colonnes d'horodatage sont présentes.Mise à jour: comme le souligne @mitsy, si cette vérification est nécessaire en dehors des rappels, utilisez
id_previously_changed?
. Voir la documentation .la source
after_save
.id_changed?
sera faux après l'enregistrement de l'enregistrement (au moins en dehors des hooks). Dans ce cas, vous pouvez utiliserid_previously_changed?
Pas de magie des rails ici que je sache, vous devrez le faire vous-même. Vous pouvez nettoyer cela en utilisant un attribut virtuel ...
Dans votre classe de modèle:
la source
Une autre option, pour ceux qui n'ont un horodatage:
updated_at
la source
created_at
d'égalerupdated_at
dans unafter_save
rappel à tout moment autre que lors de sa création?"created_at
etupdated_at
sera égal dans unafter_save
rappel. Dans toutes les autres situations, ils ne seront pas égaux dans leafter_save
rappel.Il y a un
after_create
rappel qui n'est appelé que si l'enregistrement est un nouvel enregistrement, après sa sauvegarde . Il existe également unafter_update
rappel à utiliser s'il s'agissait d'un enregistrement existant qui a été modifié et enregistré. Leafter_save
rappel est appelé dans les deux cas, après l'unafter_create
ou l' autreafter_update
.À utiliser
after_create
si vous avez besoin que quelque chose se produise une fois après l'enregistrement d'un nouvel enregistrement.Plus d'informations ici: http://api.rubyonrails.org/classes/ActiveRecord/Callbacks.html
la source
Étant donné que l'objet a déjà été enregistré, vous devez examiner les modifications précédentes. L'ID ne doit changer qu'après une création.
Il existe également une variable d'instance
@new_record_before_save
. Vous pouvez y accéder en procédant comme suit:Les deux sont assez laids, mais ils vous permettraient de savoir si l'objet a été nouvellement créé. J'espère que cela pourra aider!
la source
after_save
rappel utilisant Rails 4 et aucun d'eux ne travaille pour identifier ce nouvel enregistrement.@object.previous_changes[:id].any?
c'est assez simple et élégant. Cela fonctionne pour moi une fois l'enregistrement mis à jour (je ne l'appelle pas depuisafter_save
).@object.id_previously_changed?
est un peu moins moche.after_save
Rails 4 que vous voudriez regarder auchanges[:id]
lieu deprevious_changes[:id]
. Cependant, cela change dans Rails5.1 (voir la discussion sur github.com/rails/rails/pull/25337 )previous_changes.key?(:id)
pour une meilleure compréhension.Rails 5.1+ façon:
la source
Pour Rails 4 (vérifié sur 4.2.11.1), les résultats de
changes
et lesprevious_changes
méthodes sont des hachages vides{}
lors de la création d'objets à l'intérieurafter_save
. Ainsi, desattribute_changed?
méthodes comme celles-id_changed?
ci ne fonctionneront pas comme prévu.Mais vous pouvez profiter de cette connaissance et - sachant qu'au moins 1 attribut doit être présent lors
changes
de la mise à jour - vérifiez s'ilchanges
est vide. Une fois que vous confirmez qu'il est vide, vous devez être lors de la création de l'objet:la source
J'aime être précis même si je suis conscient que cela
:id
ne devrait pas changer normalement, maisIl est toujours moins cher d'être précis au lieu de trouver un bug inattendu très étrange.
De la même manière si j'attends le
true
drapeau d'un argument non fiableCela permet de gagner beaucoup d'heures pour ne pas rester assis sur des bugs étranges.
la source