Active
Project:
References
Version:
7.x-2.x-dev
Component:
Code: node_reference
Priority:
Normal
Category:
Feature request
Assigned:
Unassigned
Issue tags:
Reporter:
Created:
28 Sep 2009 at 03:25 UTC
Updated:
9 Dec 2011 at 21:31 UTC
How to reproduce:
You may wonder, "Hey, idiot, tell us how you constructed the filter in step 3." Well, that's the point--there is no way to construct a filter that says find all fields with an empty or invalid nodereference.
Now you may counter, "Hey, idiot, select Is none of and select everything to the right." Nope: this filter will not be correct as soon as new Engine nodes are added.
We need a way to have one filter that includes nodes with empty or invalid nodereferences. From a practical perspective, either is equivalent.
Comments
Comment #1
markus_petrux commentedThis is probably because the node reference module does not touch a reference field when the referred node is deleted.
I would suggest trying http://drupal.org/project/cck_referential_integrity
Comment #2
aren cambre commentedShouldn't this be folded into CCK core? This is not really a boundary case--it can happen to any Drupal admin.
Comment #3
markus_petrux commentedAs a feature request, I'm afraid it won't happen. That's why I wrote that module.
Comment #4
markus_petrux commentedFor the record:
- #83929: referential integrity
- #362649: Inconsistent site left after deleting a parent referenced in a nodereference field
Comment #5
aren cambre commentedI thought about this more. When a Drupal admin sets a filter to see if there is no node reference, virtually all the time he doesn't care if it's null or invalid. Either way is the same: no node reference.
In the above example, if you visit the ChevyNova node, you will see no referenced Engine node even though its node reference field has data.
Suppose you had that ChevyNova node and a new FordFalcon node that has a true null node reference field. How do you create a valid node reference? It's the same either way: set a new node reference through the Drupal UI/API or hack the database.
I think this discussion is getting hung up on SQL logic and computer science way of viewing the problem, not on what the user would actually want.
To summarize: A strict check for a null value misses the point. Since Drupal has no built in referential integrity, and since the vast majority of Drupal admins are not using the Referential Integrity module per http://drupal.org/project/usage/cck_referential_integrity:
Adding Usability tag because I think this is a usability bug.
Comment #6
markus_petrux commentedSo the other issue was first. This one is a dup of #362649: Inconsistent site left after deleting a parent referenced in a nodereference field. Note that yched said "won't fix". And I'm afraid this won't happen in CCK for D6. You may try to see how this is being addressed in Fields in D7.
Comment #7
aren cambre commentedSorry if I was unclear, but I am saying that until Drupal has referential integrity, the filters must anticipate conditions that can exist because of the lack of referential integrity.
When we filter for nodes with no node reference, the filter must return nodes with either null or invalid node references.
Only once (if?) referential integrity is implemented is it OK for this filter to filter only on null node references.
Comment #8
markus_petrux commentedHave you tried adding a relationship for the corresponding nodereference field and setting this relationship to required?
Comment #9
aren cambre commentedNo, but shouldn't the filter "just work" without that step?
Comment #10
markus_petrux commentedWell, if you need to check if the nid on a nodereference field points to an existing node or not, you need the relationship, no?
Comment #11
aren cambre commentedCan I do it? Probably. Does this workaround comply with the spirit of Dries's usability improvement mandate? No. The filter should "just work."
If it is impossible to make the filters smarter, then the UI needs to be adjusted to make it clear to novices that the nodereference "is empty" filter is broken because of product design and may produce inaccurate results.
Comment #12
markus_petrux commentedAFAICT, the empty filter just works. I think you really mean CCK needs a valid reference filter, and this is something that can only be done with a join, which is what the relationship provides.
However, the correct way to deal with this is that something would have to ensure deleted nodes are dereferenced, but it was said "won't fix", and that's why I implemented CCK I.R. module.
Please note I'm almost alone dealing with CCK issues, and I'm just trying to help you address a problem. CCK for D6 is basically feature frozen because no one is working on it. CCK developers are busy with Fields in D7, and any relative complex change here will probably be discarded. If I was under your skin, I would try to look at how things are being done with Fields in D7, and try to help there. Anything we do here may lead to nowhere if that's not implemented for Fields in D7.
Comment #13
aren cambre commentedThanks.
Re: "won't fix"--I understand your view and appreciate the I.R. module. I still believe, however, that until referential integrity is in core or your module gets popular, modules have to deal with the lack of RI.
Re: "D7": I'll switch this to D7 and see if a current maintainer is aware whether it has been fixed. If not, now is time to get the fix in.
Comment #14
karens commentedMove to new References module.
Comment #15
fgmCategorizing.
Comment #16
fgmI just tested the mechanism described by markus_petrux at #6 on the current reference 7.2 and views 7.3 version and it works well.
Since References is essentially a port of nodereference/userreference instead of a new complete solution, and that workaround works well, I'm inclined to won't fix.
Comment #17
aren cambre commentedI don't see a mechanism described in #6.
Comment #18
fgmTypo: #8, as you probably guessed.
Comment #19
fgmThis really is a feature request, since the behaviour is identical to CCK D6. Accordingly postponing since we only do bug fixes until we have a stable release, at which point features will be reactivated.
Comment #20
erikwebb commentedThis certainly seems achievable without a lot of effort.
I'd be glad to take a crack at solving this problem in anticipation of a stable release (2.0-beta3 seems pretty stable to me). Does this approach sound like the correct method? If so, I'll see what I can figure out.
If we could assume field data is only in SQL, this could be done much easier with a single DELETE query for each node reference field. Since we have to support other storage backends, this won't scale for a large site with many nodes. Batch API is the next step. Should it be taken down even further to be usable only via cron?
Also, do we delete any existence of that nid in past revisions as well? If we only change the current revision, that may or may not be the published revision (@see Workbench).
Comment #21
geerlingguy commentedSubscribe. This would be great to have working. It's not causing any problems on my site, per-se, but it's annoying that the extraneous data is present until someone goes in and re-saves a node with a now-nonexistent reference.
P.S. The title seems very vague to me, but I didn't read through this issue in detail. I vote for something more like "References not deleted when referenced entity is removed."
Comment #22
yched commentedThe problem is performance : find the nodes that reference the field that is being deleted is one query per noderef field existing on the site. Then we get an arbitrary number of nodes. We need to update field values for all those nodes. This can make the execution time for a node_delete() explode arbitrarily.
Keeping references to deleted entities is also what the core taxo / file / image fields do, for that matter. Invalid references are wiped out on display. But yeah, those can fool views.
A possible approach :
1. store nids of deleted nodes and perform the cleanup on cron
2. unfool views by forcing handlers for noderef fields to join back to the node table. This only needs to affect the argument and filter handlers : there are no sort handlers for noderef (eek, actually there is - there shouldn't be, we removed them in CCK D6, sorting on nid makes no sense), and fields do not take part in the query.
Comment #23
yched commentedSide note :
1. basically means porting and integrating http://drupal.org/project/cck_referential_integrity, and hooking it on cron. Won't happen overnight, if ever
2. is possibly quite straightforward, I'll look into this.
Comment #24
yched commented"forcing the argument and filter handlers for noderef fields to join back to the node table" :
I started that, it works, but the trouble is that when the view additionally has a relationship on the noderef field (with option "require this relationship") , then we get two INNER JOINs on the node table that are not de-duplicated, because the add_relationship() method does not use ensure_table() but directly adds the table.
So, since that the current noderef arg and filter could completely be reproduced with the noderef relationship (relationship + filter/arg on node:nid through the relationship), I'm not sure keeping them makes any sense if they either :
- can be fooled by deleted nodes
- or are made more bullet-proof at the cost of a JOIN will be duplicate if the view uses an actual relationship.
I'll try to ping merlinofchaos and dereine to get their thoughts on this, since this pattern also involves Views' own arg and filters for taxo / file / image fields.
Comment #25
Adam S commentedFirst, I have very little idea what this thread is about so this might not be the correct place to put my comment.
My situation is that I have a product listing that users can attach reviews to. The reviews might be comments but they are not. There are also other node references attached to each product like a photo and administration notes. I'm not sure why I didn't use comments because they are fieldable perhaps I just didn't like the interface. However, when I delete a product there is no reason to have reviews that reference that product and they should be deleted too. I found the solution in comment.module which looks up all the cids of comments attached to a node that is being deleted and then deletes all of them.
Here is my solution:
There are a few things that References can work with here. First, it can use the hook_entity_delete() function to look up all fieldable entities that have a reference field attached to it. Second, all the information about the references are contained in the field_config and field_config_instance tables of the database. This can be queried instead of the hard coded example I have to determine if a node or entity has another node or entity with a reference to it. User options to manage orphaned references can be set with the hook_field_widget_settings_form() function. Last like the comment_delete_multiple() function in comment.module which has to also delete each comment's replies a custom function can be recursive to see if the deleted nodes that reference a node being deleted also have other entities that reference it.
Comment #26
yched commented@Adam S : yes, but see my considerations on performance in #22.
Comment #27
altavis commentedsubscribing
Comment #28
claudiu.cristeaHere's a port of http://drupal.org/project/cck_referential_integrity to Drupal 7
http://drupal.org/sandbox/claudiucristea/1263038
The main change from the D6 version is that all updates on entities are queued, using Queue API, and then processed at cron.
Fell free to test the module and use the issue queue here http://drupal.org/project/issues/1263038 to send your feedback as bug reports or feature requests. After some testing and input from the community I will promote the project as permanent project.
Comment #29
hefox commented#1346696: On deletion of node/user, references to it are not removed is an post specific to that the records aren't being cleared. Not sure which is duplicate.
(A table should be clearing out data about nodes/user on deletion -- that is a bug. Having a contrib module solve a bug with another seems a bit overdone).