J'ai réalisé quelque chose d'assez étrange en essayant de télécharger une image via le bijou Paperclip pour mon modèle d'utilisateur (sous l'attribut avatar). Pour une raison quelconque, User.update et @ user.update_attributes se comportent différemment. Est-ce que quelqu'un sait pourquoi il en est ainsi?
#using @user.update_attributes(user_avatar_params)
def update_profile_pic
@user = User.find(params[:id])
@user.update_attributes(user_avatar_params)
puts @user.avatar_file_name.nil? # prints false as expected
respond_to do |format|
format.html { redirect_to :back }
format.js
end
end
#using User.update(@user.id, user_avatar_params)
def update_profile_pic
@user = User.find(params[:id])
User.update(@user.id, user_avatar_params)
puts @user.avatar_file_name.nil? # prints true although successfully saves
respond_to do |format|
format.html { redirect_to :back }
format.js
end
end
Et voici mes paramètres forts dans le user_controller.rb
def user_avatar_params
params.require(:user).permit(:avatar)
end
MISE À JOUR
Donc, après avoir reçu des réponses rapides et impressionnantes, voici ce que j'ai appris:
User.update
Renvoie l'objet résultant, qu'il ait été enregistré avec succès dans la base de données ou non. Par conséquent, User.update(@user.id, user_avatar_params)
ne met pas à jour la variable @user si vous n'effectuez pas l'affectation. @user.update_attributes(user_avatar_params)
modifie implicitement la variable @user.
La solution pour que cela fonctionne avec la méthode de mise à jour est de faire @user = User.update(@user.id, user_avatar_params)
ActiveRecord.update
a un comportement qui peut vous décourager:
Met à jour un objet (ou plusieurs objets) et l'enregistre dans la base de données, si les validations réussissent. L'objet résultant est renvoyé, que l'objet ait été enregistré avec succès dans la base de données ou non. http://apidock.com/Rails/ActiveRecord/Base/update/class
Cependant, le update_attributes
renverra simplement false
.
Les deux utilisent des validations au niveau du modèle et les deux doivent donc enregistrer ou ne pas enregistrer de manière égale. Cependant, les valeurs de retour seront différentes.
Comme l'a souligné @RoaringStones, la solution consiste à utiliser
user = User.update(user.id, user_avatar_params)
Pour ce que ça vaut, à partir de Rails 4.0.2, #update
renvoie false
si la mise à jour a échoué, pas simplement l'objet pour lequel la mise à jour a échoué. De plus, #update_attributes
est simplement un alias de #update
maintenant.
Au fait, #update_attributes
va être déconseillé de Rails 6 (bien que ce ne soit pas encore publié)
s'il vous plaît jeter un oeil à
pour plus de détails.