Besoin de vérifier si un bloc d'attributs a changé avant la mise à jour dans Rails 3.
street1, street2, ville, état, code postal
Je sais que je pourrais utiliser quelque chose comme
if @user.street1 != params[:user][:street1]
then do something....
end
Mais ce morceau de code sera VRAIMENT long. Y a-t-il un moyen plus propre?
C'est ainsi que j'ai résolu le problème de la vérification des changements dans plusieurs attributs.
La
changed
méthode renvoie un tableau des attributs modifiés pour cet objet.Les deux
@user.changed
etattrs
sont des tableaux pour que je puisse obtenir l'intersection (voirary & other ary
méthode). Le résultat de l'intersection est un tableau. En appelantany?
le tableau, je deviens vrai s'il y a au moins une intersection.Également très utile, la
changed_attributes
méthode renvoie un hachage des attributs avec leurs valeurs d'origine et lechanges
retourne un hachage des attributs avec leurs valeurs d'origine et nouvelles (dans un tableau).Vous pouvez vérifier APIDock pour quelles versions ont pris en charge ces méthodes.
http://apidock.com/rails/ActiveModel/Dirty
la source
if attrs.any?{|attr| @user.send("#{attr}_changed?")}
Quand je veux vérifier si l'un des différents attributs a changé - Bien sûr, je ne le fais qu'avec des attrs que j'ai moi-même définis, car je n'aime pas jeter les paramètres utilisateur dans unesend
méthode. ;)ActiveModel::Dirty
n'a pas fonctionné pour moi parce que le@model.update_attributes()
cache les changements. Voici donc comment j'ai détecté des changements dans uneupdate
méthode dans un contrôleur:Si vous essayez de détecter de nombreux changements d'attributs, cela peut devenir compliqué. Ne devrait probablement pas faire cela dans un contrôleur, mais meh.
la source
previous_changes
qui est également disponible par défaut.#update_attributes
ne cache pas les changements. Il enregistre l'enregistrement, le modèle est donc mis à jour et il n'y a pas de changement. Vous devez modifier le champ dans le modèle et vérifierchanged?
avant de l'enregistrer. c'est à dire. @ model.field = 'foo' or@model.attributes = @model.attributes.merge(params[:model])
Pour les rappels de rails 5.1+
À partir de Ruby on Rails 5.1, les méthodes
attribute_changed?
etattribute_was
ActiveRecord seront obsolètesUtiliser à la
saved_change_to_attribute?
place deattribute_changed?
Plus d'exemples ici
la source
Les réponses ci-dessus sont meilleures mais pour la connaissance, nous avons également une autre approche, la valeur de la colonne 'catagory' change pour un objet (@design),
Les .changes renverront un hachage avec une clé comme nom de colonne et des valeurs sous forme de tableau avec deux valeurs [old_value, new_value] pour chaque colonne. Par exemple, la catégorie ci-dessus passe de «ABC» à «XYZ» de @design,
Pour le changement de références dans ROR
la source