From b6ed3fe3e5eb1db68eb8115e627cc4b3dcc16b9e Mon Sep 17 00:00:00 2001 From: MAEDA Go Date: Fri, 16 Oct 2026 13:03:12 +0900 Subject: [PATCH] Keep values of spent time custom fields not visible to the user when editing a time entry TimeEntry#safe_attributes= removed custom field values not visible to the user from custom_field_values. When the time entry was saved, save_custom_field_values then deleted the stored custom values of those fields, so any edit by such a user cleared them. Restore the values the hidden fields had before the assignment instead of removing them. The check still runs after the assignment because the visibility depends on the project, which may be set from issue_id. Co-Authored-By: Claude Opus 5.5 --- app/models/time_entry.rb | 13 +++++++++---- test/unit/time_entry_custom_field_test.rb | 17 +++++++++++++++++ 2 files changed, 26 insertions(+), 4 deletions(-) diff --git a/app/models/time_entry.rb b/app/models/time_entry.rb index 4c997d81e..39c42564e 100644 --- a/app/models/time_entry.rb +++ b/app/models/time_entry.rb @@ -126,6 +126,7 @@ class TimeEntry < ApplicationRecord def safe_attributes=(attrs, user=User.current) if attrs + previous_custom_field_values = custom_field_values.map(&:dup) attrs = super(attrs) if issue_id_changed? && issue if issue.visible?(user) && user.allowed_to?(:log_time, issue.project) @@ -150,10 +151,14 @@ class TimeEntry < ApplicationRecord @invalid_user_id = nil end - # Delete assigned custom fields not visible by the user - editable_custom_field_ids = editable_custom_field_values(user).map {|v| v.custom_field_id.to_s} - self.custom_field_values.delete_if do |c| - !editable_custom_field_ids.include?(c.custom_field.id.to_s) + # Restore custom field values not visible by the user + editable_custom_field_ids = editable_custom_field_values(user).map(&:custom_field_id) + custom_field_values.map!.with_index do |custom_field_value, i| + if editable_custom_field_ids.include?(custom_field_value.custom_field_id) + custom_field_value + else + previous_custom_field_values[i] + end end end diff --git a/test/unit/time_entry_custom_field_test.rb b/test/unit/time_entry_custom_field_test.rb index cd967ce29..899e56f40 100644 --- a/test/unit/time_entry_custom_field_test.rb +++ b/test/unit/time_entry_custom_field_test.rb @@ -70,4 +70,21 @@ class TimeEntryCustomFieldTest < ActiveSupport::TestCase assert_equal 'valuea', time_entry.custom_field_value(cf1) assert_nil time_entry.custom_field_value(cf2) end + + def test_safe_attributes_should_keep_values_of_custom_fields_not_visible_to_user + field = TimeEntryCustomField.create!(:name => 'Non visible field', + :field_format => 'string', + :visible => false, :role_ids => [1]) + time_entry = TimeEntry.generate!(:project_id => 1, :user_id => 3, :author_id => 3) + time_entry.custom_field_values = {field.id.to_s => 'Foo'} + time_entry.save! + + time_entry.send :safe_attributes=, { + 'comments' => 'Updated', + 'custom_field_values' => {field.id.to_s => 'Bar'} + }, User.find(3) + time_entry.save! + + assert_equal 'Foo', time_entry.reload.custom_field_value(field) + end end -- 2.55.0