Adding a Relationship to Your View? Your Results Might be Different than you Expect
The Node Access system in Drupal provides a powerful way to provide granular access to individual nodes, but it can occasionally cause unexpected problems.
Consider a case I ran into the other day: I had a View that was supposed to show all files managed by Drupal, however some users could only see a subset of the files. My initial detective work took me the wrong direction (I was using the File Entity module and spent a little time investigating its file access system) but eventually I realized that:
- Only users with the “Bypass content access control” permission could see all the files.
- The “missing” files were ones that were not used in any node.
- The first step of debugging any problem like this should always be to take a look at the actual query being run by Views.
Once I took a look at the query being generated by Views I realized my problem stemmed from the fact that my View contained an optional relationship to the node table via the file_usage table. This wouldn’t normally be a problem, but the node access system was adding node access criteria to the query in such a way that this optional relationship was effectively being made “required.” The net result for this View was that users without “Bypass content access control” (which prevents node access criteria from being added to a query) were unable to see files that were either never used on a node, or were used only on nodes which the current user was not permitted to view.
So yes, there is a bug
There’s a bug in Drupal core that causes this problem: https://drupal.org/node/1349080. There are a lot of comments on that issue, but I’ll try to offer a summary by way of an additional example. Consider a content type “album” that contains an entityreference to nodes of content type “artist.” If you have a View listing albums and add a relationship to the node table to get data about the related artist then the node access system will prevent some of your albums from being listed, even if you have permission to view all albums, and if either of the following is true:
- No artist value has been entered for the album.
- The current user is not allowed to view the artist node which the album references.
How to fix it?
You have a few options:
Patch core
At this point there’s only a patch available for Drupal 8. It hasn’t been backported to Drupal 7. There is a quasi-fix for Drupal 7 in comment #89 on that issue but it’s not totally correct and needs to be updated to use placeholders properly.
Disable SQL rewriting for your View
This was the approach I took to solve the problem I was having with my View of files. Perhaps you know you’re not displaying any sensitive data in this View are only using the joined-to table for filter criteria or something similar. In that case you can just disable SQL rewriting which will prevent the node access criteria from being added to your View. You can do this in the configuration for your View under Other → Query Settings. Be mindful when you do this because you may allow users to see data they shouldn’t be allowed to see.
Try to reconfigure your View to remove the relationship
Does the relationship to the node table exist to allow you to grab data that you’re rendering in fields in the view? You may be able to instead configure your View to output the view results via rendered entities and remove the need for the troublesome relationship entirely. Or is the relationship there to enable certain sort criteria? Consider changing the sort criteria. This won’t work for all situations (and won’t work when the relationship exists for purposes of filtering as in my case), but will be a useful approach for some.
In Conclusion
Keep a close eye out for this tricky bug. Your users might be getting blocked from seeing content (even non-node content) that they should be allowed to see!
Do you have a View that's not showing all the results you expect? Perhaps Drupal's node access system is interfering with one of your relationships.