Disons que j'ai 15 identifiants utilisateur dans un tableau appelé user_ids
.
Si je veux, disons, changer tous leurs noms en "Bob", je pourrais faire:
users = User.find(user_ids)
users.update_all( :name => 'Bob' )
Cependant, cela ne déclenche pas de rappel. Si je dois déclencher des rappels sur la sauvegarde de ces enregistrements, à ma connaissance la seule façon est d'utiliser:
users = User.find(user_ids)
users.each do |u|
u.name = 'Bob'
u.save
end
Cependant, cela signifie potentiellement une tâche très longue dans une action de contrôleur.
Donc, ma question est, existe-t-il un autre moyen meilleur/plus performant/plus efficace pour déclencher une mise à jour par lots vers un ensemble d'enregistrements qui fait déclenche les rappels sur les enregistrements?
Non, pour exécuter des rappels, vous devez instancier un objet qui est une opération coûteuse. Je pense que la seule façon de résoudre votre problème est de refactoriser les actions que vous effectuez en rappel dans une méthode distincte qui pourrait utiliser les données récupérées par la méthode select_all sans instanciation d'objet.
Au lieu d'utiliser chaque/find_each, essayez plutôt d'utiliser la méthode update
:
models.update(column: value)
Voici une autre façon de déclencher des rappels. À la place d'utiliser
models.update_all(params)
vous pouvez utiliser
models.find_each { |m| m.update_attributes(params) }
Cependant, je ne recommanderais pas cette approche si vous traitez de très grandes quantités de données.
J'espère que ça aide!