From fb486c1921841da4a934b75e1add228fc3c25420 Mon Sep 17 00:00:00 2001 From: Jan Sandbrink Date: Thu, 5 Mar 2015 17:09:20 +0100 Subject: [PATCH] fix validation in type changing cases --- lib/api/v3/work_packages/work_packages_api.rb | 20 ++++++++++++++----- .../lib/acts_as_customizable.rb | 3 +-- 2 files changed, 16 insertions(+), 7 deletions(-) diff --git a/lib/api/v3/work_packages/work_packages_api.rb b/lib/api/v3/work_packages/work_packages_api.rb index 8635bc0c37..645c8abe5b 100644 --- a/lib/api/v3/work_packages/work_packages_api.rb +++ b/lib/api/v3/work_packages/work_packages_api.rb @@ -40,18 +40,28 @@ module API def write_work_package_attributes if request_body - payload = ::API::V3::WorkPackages::Form::WorkPackagePayloadRepresenter.create( - @work_package, - enforce_lock_version_validation: true) - begin - payload.from_json(request_body.to_json) + # we need to merge the JSON two times: + # In Pass 1 the representer only has custom fields for the current WP type + # After Pass 1 the correct type information is merged into the WP + # In Pass 2 the representer is created with the new type info and will be able + # to also parse custom fields successfully + merge_json_into_work_package!(request_body.to_json) + merge_json_into_work_package!(request_body.to_json) rescue ::API::Errors::Form::InvalidResourceLink => e fail ::API::Errors::Validation.new(e.message) end end end + # merges the given JSON representation into @work_package + def merge_json_into_work_package!(json) + payload = ::API::V3::WorkPackages::Form::WorkPackagePayloadRepresenter.create( + @work_package, + enforce_lock_version_validation: true) + payload.from_json(json) + end + def request_body env['api.request.body'] end diff --git a/lib/plugins/acts_as_customizable/lib/acts_as_customizable.rb b/lib/plugins/acts_as_customizable/lib/acts_as_customizable.rb index 03a79bf23d..880d8bf15c 100644 --- a/lib/plugins/acts_as_customizable/lib/acts_as_customizable.rb +++ b/lib/plugins/acts_as_customizable/lib/acts_as_customizable.rb @@ -46,7 +46,6 @@ module Redmine order: "#{CustomField.table_name}.position", dependent: :delete_all, validate: false - before_validation { |customized| customized.custom_field_values if customized.new_record? } validate :validate_custom_values send :include, Redmine::Acts::Customizable::InstanceMethods # Save custom values when saving the customized object @@ -119,7 +118,7 @@ module Redmine end def validate_custom_values - custom_values.reject(&:marked_for_destruction?).select(&:invalid?).each do |custom_value| + custom_field_values.reject(&:marked_for_destruction?).select(&:invalid?).each do |custom_value| custom_value.errors.each do |_, message| errors.add(custom_value.custom_field.accessor_name.to_sym, message) end