Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added a check for configured field name conflict with inherited methods #9549

Open
wants to merge 2 commits into
base: 4
Choose a base branch
from

Conversation

jakxnz
Copy link
Contributor

@jakxnz jakxnz commented Jun 16, 2020

#6329

Added a sanity check which throws an error if a configured $db field has the same name as a method in the parent-level scope. Ignores TestOnly classes

image

@jakxnz jakxnz force-pushed the pulls/4/guard-against-field-vs-parent-method-conflict branch from e8bff5d to 2a59b1b Compare June 17, 2020 00:54
@@ -3451,6 +3452,17 @@ public function requireTable()
);
}

// Sanity check for fields that conflict with parent
foreach (array_keys($fields) as $fieldName) {
if (method_exists(get_parent_class($this), $fieldName) && !($this instanceof TestOnly)) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Shouldn't we use singleton(get_parent_class($this))->hasMethod($fieldName)) so that we can check for methods added by extensions?

this does also pose the question of how we handle extensions that are added after the model has been defined. eg: adding an extension as a feature request on top of a pre-existing site

Copy link
Contributor Author

Choose a reason for hiding this comment

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

🤔 True that. And maybe reduce the interrupt to a warning (similar to DBSchemaManager::requireTable()?) and add something like a $ignore_conflicting_fields = [] config to give users the ability to suppress the warning?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@dhensby any thoughts?

Copy link
Member

Choose a reason for hiding this comment

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

The fact that there's a need to block this on test classes is a bit of a code smell: why is that needed and why would it never be needed in a non-test case?

Copy link
Member

Choose a reason for hiding this comment

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

Also what about the "get$fieldName" method?

Copy link
Member

Choose a reason for hiding this comment

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

Should there be similar checks for relations?

Copy link
Member

Choose a reason for hiding this comment

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

+1 for reducing the error to a warning. With that in place I think we can avoid the need for a suppression filter.

This does also pose the question of how we handle extensions that are added after the model has been defined.

You're going to have a conflicting situation. Right now the system blindly lets you build a corrupt, inconsistent app. Warning that you're doing this but leaving behaviour otherwise unchanged seems fine. In such a case a developer would be advised to refactor their site to avoid conflicts, which would be the best way to get rid of the warning message. Otherwise they can suppress warnings application-wide if they're that much of a cowboy ;)

Copy link
Member

@sminnee sminnee left a comment

Choose a reason for hiding this comment

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

A few comments. I'm skeptical that blocking this behaviour for tests is a good idea.

@@ -3451,6 +3452,17 @@ public function requireTable()
);
}

// Sanity check for fields that conflict with parent
foreach (array_keys($fields) as $fieldName) {
if (method_exists(get_parent_class($this), $fieldName) && !($this instanceof TestOnly)) {
Copy link
Member

Choose a reason for hiding this comment

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

Also what about the "get$fieldName" method?

@@ -3451,6 +3452,17 @@ public function requireTable()
);
}

// Sanity check for fields that conflict with parent
foreach (array_keys($fields) as $fieldName) {
if (method_exists(get_parent_class($this), $fieldName) && !($this instanceof TestOnly)) {
Copy link
Member

Choose a reason for hiding this comment

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

Should there be similar checks for relations?

Copy link
Member

@sminnee sminnee left a comment

Choose a reason for hiding this comment

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

  • Clarify why is the TestOnly filter is needed and why would it never be needed in a non-test case. Ideally, remove this constraint.
  • Consider the "get$fieldName" method too and similar checks for relations?
  • Reduce the error to a warning

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[ORM] Database field names are not guarded against ORM method clashes
4 participants