web-dev-qa-db-fra.com

Comment déterminer si un enregistrement vient d'être créé ou mis à jour dans after_save

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 nouvel enregistrement créé ou un ancien à partir de la mise à jour?

J'espère ne pas utiliser un autre rappel tel que before_create pour 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é.

Modifier: besoin de le déterminer dans after_save hook, et pour mon cas d'utilisation particulier, il n'y a pas updated_at ou updated_on horodatage

89
Aaron Qian

Je cherchais à l'utiliser pour un after_save rappeler.

Une solution plus simple consiste à utiliser id_changed? (car cela ne changera pas sur update) ou même created_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 docs .

156
Zubin

Non Rails magie ici que je sache, vous devrez le faire vous-même. Vous pouvez nettoyer cela en utilisant un attribut virtuel ...

Dans votre classe modèle:

def before_save
  @was_a_new_record = new_record?
  return true
end

def after_save
  if @was_a_new_record
    ...
  end
end
30
Jeff Paquette

Encore une autre option, pour ceux qui font ont un updated_at horodatage:

if created_at == updated_at
  # it's a newly created record
end
24
colllin

Il y a un after_create rappel qui n'est appelé que si l'enregistrement est un nouvel enregistrement, après sa sauvegarde . Il y a aussi un after_update rappel à utiliser s'il s'agissait d'un enregistrement existant qui a été modifié et sauvegardé. Le after_save le rappel est appelé dans les deux cas, après que after_create ou after_update est appelé.

Utilisation after_create si quelque chose doit se produire une fois qu'un nouvel enregistrement a été enregistré.

Plus d'informations ici: http://api.rubyonrails.org/classes/ActiveRecord/Callbacks.html

23
sharpone

Étant donné que l'objet a déjà été enregistré, vous devez consulter les modifications précédentes. L'ID ne doit changer qu'après une création.

# true if this is a new record
@object.previous_changes[:id].any?

Il existe également une variable d'instance @new_record_before_save. Vous pouvez y accéder en procédant comme suit:

# true if this is a new record
@object.instance_variable_get(:@new_record_before_save)

Les deux sont assez laids, mais ils vous permettraient de savoir si l'objet a été nouvellement créé. J'espère que ça t'as aidé!

16
Tom Rossi