From 6a2bce19317b05f1eab56f82ced58a248db90d94 Mon Sep 17 00:00:00 2001 From: Philipp Daniels Date: Sat, 16 Dec 2017 03:16:22 +0100 Subject: [PATCH] FIX: Data loss on update of single user_field. https://meta.discourse.org/t/api-data-loss-caused-by-changed-behaviour-of-custom-user-field-update/74990 --- app/controllers/users_controller.rb | 5 ++++- app/models/user.rb | 1 + spec/controllers/users_controller_spec.rb | 21 +++++++++++++++++++++ 3 files changed, 26 insertions(+), 1 deletion(-) diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb index 593a402ea70..3ce9e029bc9 100644 --- a/app/controllers/users_controller.rb +++ b/app/controllers/users_controller.rb @@ -113,7 +113,10 @@ class UsersController < ApplicationController fields = UserField.all fields = fields.where(editable: true) unless current_user.staff? fields.each do |f| - val = params[:user_fields][f.id.to_s] + field_id = f.id.to_s + next unless params[:user_fields].has_key?(field_id) + + val = params[:user_fields][field_id] val = nil if val === "false" val = val[0...UserField.max_length] if val diff --git a/app/models/user.rb b/app/models/user.rb index e44b0c665b0..28dc1e85522 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -312,6 +312,7 @@ class User < ActiveRecord::Base @unread_notifications = nil @unread_total_notifications = nil @unread_pms = nil + @user_fields = nil super end diff --git a/spec/controllers/users_controller_spec.rb b/spec/controllers/users_controller_spec.rb index b1c527b29fa..b48f46e1d4b 100644 --- a/spec/controllers/users_controller_spec.rb +++ b/spec/controllers/users_controller_spec.rb @@ -1533,6 +1533,27 @@ describe UsersController do expect(user.user_fields[user_field.id.to_s].size).to eq(UserField.max_length) end + + it "should retain existing user fields" do + put :update, params: { + username: user.username, name: 'Jim Tom', user_fields: { user_field.id.to_s => 'happy', optional_field.id.to_s => 'feet' } + }, format: :json + + expect(response).to be_success + expect(user.user_fields[user_field.id.to_s]).to eq('happy') + expect(user.user_fields[optional_field.id.to_s]).to eq('feet') + + put :update, params: { + username: user.username, name: 'Jim Tom', user_fields: { user_field.id.to_s => 'sad' } + }, format: :json + + expect(response).to be_success + + user.reload + + expect(user.user_fields[user_field.id.to_s]).to eq('sad') + expect(user.user_fields[optional_field.id.to_s]).to eq('feet') + end end context "uneditable field" do