Skip to content

Feature/69034 change enforcement of project attributes on creation for templates#21055

Merged
dombesz merged 3 commits into
devfrom
feature/69034-change-enforcement-of-project-attributes-on-creation-for-templates
Nov 19, 2025
Merged

Feature/69034 change enforcement of project attributes on creation for templates#21055
dombesz merged 3 commits into
devfrom
feature/69034-change-enforcement-of-project-attributes-on-creation-for-templates

Conversation

@dombesz
Copy link
Copy Markdown
Contributor

@dombesz dombesz commented Nov 17, 2025

Ticket

https://community.openproject.org/wp/69034

What are you trying to accomplish?

Screenshots

Blank project does show the required project attributes

image

Creating a project from templates does not show and require the project attributes

image

What approach did you choose and why?

  • Deactivate the custom field validation on the SetAttributesContract when a special contract option is passed skip_custom_field_validation: true.
  • Pass the flag from the projects controller down to the contract via the copy job and service.
  • Hide the custom fields on the project creation form when a template is chosen.
  • Store the template_id on the projects created from a template.

Merge checklist

  • Added/updated tests
  • Added/updated documentation in Lookbook (patterns, previews, etc)
  • Tested major browsers (Chrome, Firefox, Edge, ...)

@dombesz dombesz force-pushed the feature/69034-change-enforcement-of-project-attributes-on-creation-for-templates branch 2 times, most recently from 6f1ac74 to 6525755 Compare November 17, 2025 12:23
Base automatically changed from feature/68856-new-project-template-selector to dev November 18, 2025 11:51
@dombesz dombesz force-pushed the feature/69034-change-enforcement-of-project-attributes-on-creation-for-templates branch from 6525755 to 3c9d201 Compare November 18, 2025 12:26
@EinLama EinLama self-requested a review November 18, 2025 15:20
Copy link
Copy Markdown
Contributor

@EinLama EinLama left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It works, well done 🚀

I am wondering about the state that we carry around in acts_as_customizable, see my comment there. And I have an issue with one spec that is missing a useful expectation. Otherwise, this looks great.

Projects::Settings::NameForm.new(f),
Projects::Settings::RelationsForm.new(f),
Projects::Settings::CustomFieldsForm.new(f)
*(Projects::Settings::CustomFieldsForm.new(f) unless template)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TIL about this use case of the splat operator. I longed for something like this many times, but didn't know about it. That's great!

else
custom_field_values
end
@custom_values_to_validate ||= persisted? ? [] : custom_field_values
Copy link
Copy Markdown
Contributor

@EinLama EinLama Nov 18, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a subtle change in logic. Now, a record that is validated multiple times will only consider custom values that were there for the first validation - since these are cached.
Also, as soon as the AttributeService calls #deactivate_custom_field_validations!, that deactivation change is permanent until the record is reloaded.
For the use cases that I can think of, this assumption works and will cause no problems. But if it leads to bug, that one would be hard to find 😅 That being said, I could not provoke this to happen in the wizard.

Copy link
Copy Markdown
Contributor Author

@dombesz dombesz Nov 19, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, that is an interesting point, that could happen for example, if custom values are changed between 2 validation calls on the object. We also cache the available_custom_fields array, so that variable is also susceptible for this issue. I think it's safe to assume with the current codebase it's not going to cause a problem. Edit: True but not relevant.

Edit2: A potential solution would be to store the custom fields to be validated, instead of the custom values. Then in the validate_custom_values method, always validate the fresh list of custom values.

def validate_custom_values
custom_values_to_validate
.uniq
.reject { |cv| cv.marked_for_destruction? || cv.calculated_value? }
.select(&:invalid?)
.each { |custom_value| add_custom_value_errors! custom_value }
end

Something like:

def validate_custom_values
  custom_field_values
    .select { |cfv| cfv.custom_field.in?(custom_fields_to_validate) }
    .uniq
    .reject { |cv| cv.marked_for_destruction? || cv.calculated_value? }
    .select(&:invalid?)
    .each { |custom_value| add_custom_value_errors! custom_value }
end

Since this requires a bigger change, I created a maintenance ticket to address this separately.

let(:contract_options) { { skip_custom_field_validation: true } }
let(:project) { create(:project) }

it "deactivates custom field validations" do
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new specs in this file check that a method is called. It does not verify anything else.

I think it should check the services result instead and verify that setting this parameter influences the validation.

There is the nice feature spec that does check the change in validation already, but since the AttributeService is a key actor for that, it deserves its own spec.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well spotted, updated the specs e16e0bd .

Comment thread app/models/project.rb
@dombesz dombesz requested a review from EinLama November 19, 2025 15:11
Copy link
Copy Markdown
Contributor

@EinLama EinLama left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice. With the maintenance ticket to investigate and fix the caching trouble and the added spec, this looks good to me ✅

@dombesz dombesz force-pushed the feature/69034-change-enforcement-of-project-attributes-on-creation-for-templates branch from e16e0bd to 2e29ca3 Compare November 19, 2025 18:14
@dombesz dombesz merged commit 63a34d2 into dev Nov 19, 2025
17 of 18 checks passed
@dombesz dombesz deleted the feature/69034-change-enforcement-of-project-attributes-on-creation-for-templates branch November 19, 2025 19:21
@github-actions github-actions Bot locked and limited conversation to collaborators Nov 19, 2025
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Development

Successfully merging this pull request may close these issues.

2 participants