Rails Paperclip:update与update_attributes
当我尝试通过paperclip gem为我的用户模型(在avatar属性下)上传图像时,我意识到了一些非常奇怪的事情。 出于某种原因,User.update和@ user.update_attributes的行为有所不同。 有谁知道为什么会这样?
#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
这是我在user_controller.rb中的强大参数
def user_avatar_params params.require(:user).permit(:avatar) end
UPDATE
因此,在收到提示和令人敬畏的回复之后,这就是我所学到的:
User.update
返回结果对象,无论它是否已成功保存到数据库。 因此,如果您不进行分配, User.update(@user.id, user_avatar_params)
不会更新@user变量。 @user.update_attributes(user_avatar_params)
确实隐式更改了@user变量。
使用update方法的解决方案是执行@user = User.update(@user.id, user_avatar_params)
ActiveRecord.update
有一个可能会让你ActiveRecord.update
的行为:
如果validation通过,则更新对象(或多个对象)并将其保存到数据库。 无论对象是否已成功保存到数据库,都会返回结果对象。 http://apidock.com/rails/ActiveRecord/Base/update/class
但是update_attributes
只会返回false
。
这两个都使用模型级validation,因此两者都应该保存或不保存。 但是,返回值将不同。
正如@RoaringStones指出的那样,解决方案就是使用
user = User.update(user.id, user_avatar_params)
对于它的价值,从Rails 4.0.2开始,如果更新失败,#update会返回false
,而不仅仅是更新失败的对象。 另外值得注意的是, #update_attributes
#update
现在只是#update_attributes
的别名。
顺便说一句, #update_attributes
将从Rails 6中弃用(尽管尚未发布)
请看看
- https://github.com/rails/rails/pull/31998
- https://github.com/rails/rails/commit/5645149d3a27054450bd1130ff5715504638a5f5
更多细节。