Support for Drupal 7 is ending on 5 January 2025—it’s time to migrate to Drupal 10! Learn about the many benefits of Drupal 10 and find migration tools in our resource center.
Problem/Motivation
When a relationship is removed there is no check whether other handlers depend on it. Thus it is possible to save a view with inconsistent data. This results in fatal errors when trying to process the view.
Proposed resolution
- Check for dependent handlers on form level when relationship is removed. If dependent handlers found, deny removal.
- Add check to DisplayPluginBase:validate().
- Add check to HandlerBase::access() so that if a required relationship doesn't exist, exclude handler from view processing.
Steps to reproduce:
- create a view to display a list of fields
- add a relationship
- add a field based on the relationship described above
- delete the relationship
- save the view
Comment | File | Size | Author |
---|---|---|---|
#53 | ScreenShot Error-message-while-saving.png | 377.86 KB | swetashahi |
#53 | Screenshot_ofView_with_relatioship.png | 384.76 KB | swetashahi |
#39 | fix-missing-relationship-2204037-39.patch | 11.28 KB | Lendude |
#39 | interdiff-2204037-31-39.txt | 15.39 KB | Lendude |
#31 | fix-missing-relationship-2204037-31.patch | 22.81 KB | kpv |
Comments
Comment #1
er.pushpinderrana CreditAttribution: er.pushpinderrana commentedUnable to reproduce this issue with
drupal 8.0-alpha10
release.Comment #2
netw3rker CreditAttribution: netw3rker commentedI just tried to reproduce this as well and couldn't. the steps i attempted were:
1) fresh 8.x-dev install
2) create content view
3) add the user-created relationship
4) add the fields user->created and user->last login
5) delete the relatinship
6) preview
I'm not sure that deleting the view is what you actually meant for step 4 since you can't delete it, then click save (its already gone). If there's a step missing please let us know.
My steps to reproduce weren't without error though. What does happen however is a SQL error is thrown because the table the fields need doesn't exist anymore. It might make sense to have the relationship not be removable until fields that depend on it (and only it) are removed.
Thoughts?
Comment #3
dawehnerWe should do two things here:
Comment #4
kpv CreditAttribution: kpv commentedhere's what I get when following #2:
Comment #5
kpv CreditAttribution: kpv commentedI wonder if this is ok:
Also noticed a strange behaviour:
Set views as described in #2 and then remove the relationship - "last login" will be broken but "created" will show content's created date. Obviously it happens because content and user entities both have "created" property.
Comment #6
kpv CreditAttribution: kpv commentedComment #8
kpv CreditAttribution: kpv commentedRegarding the previous test fail and the fix:
Is it a fair assumption that if:
(!empty($this->options['relationship'])) {
then:
$relationships = array_keys($this->view->display_handler->getHandlers('relationship'));
won't be undefined, i.e.view
anddisplay_handler
will be set for the current instance?Comment #10
kpv CreditAttribution: kpv commentedfixed views test
Comment #11
kpv CreditAttribution: kpv commentedComment #12
kpv CreditAttribution: kpv commentedComment #13
kpv CreditAttribution: kpv commentedComment #14
kpv CreditAttribution: kpv commentedComment #16
dawehnerInteresting work, will have a deep look in it tomorrow! Thank you for your great work!
Comment #17
kpv CreditAttribution: kpv commentedAlso have a look at notice at #5. Maybe it's a subject for a separate issue. I mean, it could point at some architectural drawbacks.
Comment #18
dawehnerSo in wonder whether we really have to do that on runtime or can't just always do that on save time.
Can we list which handlers are using it?
Comment #19
kpv CreditAttribution: kpv commentedComment #21
kpv CreditAttribution: kpv commentedComment #22
adci_contributor CreditAttribution: adci_contributor commentedComment #24
kpv CreditAttribution: kpv commentedComment #26
kpv CreditAttribution: kpv commentedOne of the tests in #21 (
views/src/Tests/Plugin/DisplayTest::testDisplayPlugin()
) failed becauseViewExecutable::getHandlers($type, $display_id)
sets current display to$display_id
(if given), and doesn't restore it to the previous value before return. Currently this was fixed by changing the test. If it is a bug, I suppose, it should be fixed in a separate issue.upd: Added a follow-up issue #2408613: ViewExecutable::getHandlers() should restore display_id before return.
Comment #27
kpv CreditAttribution: kpv commentedadded a minor comment
Comment #28
kpv CreditAttribution: kpv commentedRemoved test fix (since #2408613: ViewExecutable::getHandlers() should restore display_id before return was fixed).
Imo, this one is ready for final review.
Comment #29
dawehnerIts great to have some kind of test coverage here.
Honestly: I would rather move the logic into the display than into the view storage object, which once had the idea to just store stuff, and be kinda stupid otherwise. At least it would be nice to extract all the logic below into a method.
Comment #30
ivan.chavarro CreditAttribution: ivan.chavarro commentedHi,
I have reviewed the patch and it works when I remove the relationship from the "Configure Relationship" Form.
Unfortunately In "Rearrange relationships" form it allows to remove, unless it has dependencies, so the user is forced to cancel the submit form to revert the relationship removal.
Comment #31
kpv CreditAttribution: kpv commented@ivan.chavarro
Thanks, added "rearrange" form validation.
Comment #32
dawehnerThe point in #29 though is still true :(
Comment #33
kpv CreditAttribution: kpv commentedComment #34
givingxsharing CreditAttribution: givingxsharing commentedI applied the patch and it works for me in both the Rearrange Relationship form and the Configure Relationship form. Thanks!
Comment #35
kpv CreditAttribution: kpv commented@dawehner
What kind of test coverage did you mean in #29 ?
Comment #36
jcnventura CreditAttribution: jcnventura at Wunder commentedReviewing this in the mentored core sprints. Contributor tasks:
https://www.drupal.org/contributor-tasks/review
Comment #37
akozma CreditAttribution: akozma commentedI applied the patch #31 but the result has a strange behavior which is not so user friendly.
Steps:
1) fresh 8.0.x install
2) create content view
3) add the "Content: Content author" relationship
4) add the field "User: Name"
5) delete the relationship
Result:
- the relationship has been removed
- the error message appears "You can not remove this relationship because it is used by other handlers (field: name)."
Problem:
- the message "You can not remove this relationship..." doesn't contains information about the removed relationship
- can't use the "Cancel" button in order to cancel the current changes (I got the same configuration + the error message mentioned above)
Tip:
- the solution would be more user friendly if the relationship could be deleted only if there are no other dependencies, in other case a validation message will popup
Comment #38
lokapujyaI think I performed the same steps, but got slightly different results.
After deleting the relationship and hitting apply, I got the message: You can not remove "uid" relationship because it is used by other handlers (field: name).
Cancel button works.
Comment #39
LendudeAs @dawehner pointed out in #18, it would be better to check this at save. The number of scenarios that can lead to this (defaulted field vs overridden relationships, vice versa, multiple displays with different fields and relationships) makes checking this at run time pretty doomed I feel.
Also, when I'm editing my View I don't want to be bothered with "You can't do that" messages before I'm all the way done.
So, major overhaul. Just validation in the display at save. Lets see how this tests.
Comment #40
xjmThe core committers and Views maintainers (alexpott, xjm, effulgentsia, tim.plunkett, and dawehner) agreed that this is a major issue. A fatal is being caused under normal administrative site operation.
Comment #41
xjmComment #42
dawehnerLooks reasonable for me
Comment #43
lokapujyaI noticed that I was unable to cancel after removing the relationship (as described in #37). Without the patch, I can cancel.
Comment #44
lokapujyaIs there some way to check if the Action is Cancel and skip validation?
For example:
Notice that without the patch Cancel brings you out of the edit and back to the views list.
Comment #45
Lendude@lokapujya I haven't tested this yet but 'Views validates displays on Cancel' sound like an issue unrelated to this patch. So if it is indeed a more generic issue, shouldn't we just open an issue for that and RTBC this one?
Comment #46
dawehner+1
This patch solves a problem and doesn't introduce a new one.
Comment #47
lokapujyaOK, created a new issue: https://www.drupal.org/node/2671182
Comment #48
catchThis validates when a relationship has been removed and the view is saved.
But could we not validate when the relationship itself is removed or at least warn then? When you get here it's a bit late.
I can't decide whether it's more annoying to not be able to remove the relationship or not be able to save the view, but feels like the latter is probably more annoying. Obviously both are less annoying than fatal errors so if that would be much harder to implement could move to a follow-up - we already have the validation meta.
Comment #49
Lendude@dawehner argued against that in #18 and me in #39
I personally feel that not being able to remove the relationship is more annoying because it forces a workflow on me (remove all references to relationship first then remove relationship), where I feel that its a good thing that the UI doesn't bother me with errors while I'm mucking about until I tell it I'm actually done with all my changes, but that might just be me.
Comment #50
kpv CreditAttribution: kpv commented@Lendude
this reverts a test fix which wouldn't pass one of the checks you removed in #39
Comment #51
Lendude@kpv sorry, I don't follow. The test that was in HandlerTest is basically the same as the one that is now in DisplayTest. Not sure what you are referring to.
Comment #52
lokapujyaValidating would force the site builder to remove the fields before removing the relationship. Validating on save doesn't force a workflow.
How would a warning work? Maybe this discussion should happen in the views validation meta?
Doesn't that test only make sense when validating the relationship, but not when validating on save.
Comment #53
swetashahi CreditAttribution: swetashahi at Srijan | A Material+ Company commentedI tested this using Simplytest.me on a chrome browser using the patch in #39
Steps followed
1. Created a content type and added a content
2. Created a view and added fields from new content type
3. Created a relationship author
4. Added another field to the view User: Name
Screenshot here
5. Now deleted the relationship by clicking Rearrange->Remove
6. In Preview section, the warning showed up that "The field User: Name uses a relationship that has been removed. "
7. On clicking Save, got the error "The field User: Name uses a relationship that has been removed."
Screenshot here
8. I was able to cancel the relationship deletion at relationship screen and also edit view screen
Thanks @alexpott for the "ask-to-test"
Comment #54
swetashahi CreditAttribution: swetashahi at Srijan | A Material+ Company commentedComment #55
catchThat warning showing up is enough to cover my concern from #48, great that this already happens when the relationship gets removed.
Committed/pushed to 8.1.x and cherry-picked to 8.0.x. Thanks!
I added issue credit for dawehner, swetashahi and lokapujya.