Drupal 7 Views Preview Shows Different Results
OK, so you are a site builder or a privileged role building a view. In the preview you see a certain result set, but regular and/or anonymous users see only subset of those results or no results at all.
You checked all your basics. Views permissions look good; Content permissions look correct as well.
You double checked above by previewing nodes included in the view (same for related nodes if any) as a regular or anonymous user. But, alas, they are not seeing expected view results. This issue caused me a lot of grief and made me believe in gremlins for a minute, so I hope this blog post saves you some time and few gray hairs.
If you are experiencing similar issue and your case meets the following criteria:
- You are using entityreference module and there is a relationship between two entities via field entity reference.
- Your view includes those entities and joins the tables via relationship.
- You use one of the modules that works with node_access (e.g. content_access, og_access etc.). You can check node_access table in the database and if you see more than one entry in that table, you meet this criteria.
- Entity reference field which you use to form view relationship between your entities is not a required field and there are some nodes without reference.
Then this post applies to your case (skip to the bottom for solution).
In my scenario this occurred, during local testing of a D7 to D7 migration and the offending content and view worked just fine on the source D7 website. Same versions of core and all modules involved. To make things more interesting that view was a services_view and was used to generate RESTish endpoint. I had no obvious suspects. It can be many different things. Could be a bug in services, views, entityreference or something getting lost during migration. It is my first time writing migration scripts so it's very likely. Least suspicious in that list is Drupal core. This somewhat complex relationship clouds my google foo and I'm not really finding much. I scanned through each of the module's issue queues, but I'm failing to find anything similar to issues I am having. This increased my suspicions that it is probably something with my migration scripts.
It was time to roll up the sleeves and get the good ole step debugger and follow drupal execution path, recursive calls, inspect memory and generated queries on both websites and find out what's different. After hours of staring at code, refining breakpoints and looking at different drupal configs and maze of join queries I noticed something. Destination D7 had one of the subqueries altered via node_query_node_access_alter while the source didn't. In addition, this is where the query checked for existence of referenced entity's id, but didn't check for null values. Given that my view didn't enforce relationship, this was a drupal core bug.
If we have a left join, that is 'Require this relationship' is not checked (inner join otherwise), then the null value for referenced entity should be a valid one. Awesome, I need to write a core patch and check for this condition. This is super exciting. My first core contribution, my time to shine... Before I submit a new core issue and a patch, let me look at the existing queue and see if someone posted about it there. Now that I know what I'm looking for it only takes one search and I find the issue from 2 years ago: https://www.drupal.org/node/1969208.
The Drupal community delivers again. While I was a bit disappointed that I didn't get to write the patch, I found some consolation in the fact that I wasn't the only one struggling to figure this one out. Couple of days after I found this, one of the teams at Metal Toad ran into the same issue on a different project so I was able to help there as well.
While the working patch and tests for D7 are done, this won't get a D7 merge until the solution has been ported to D8. It might take a bit for merge to occur. I wrote this blog post to help increase visibility to the issue and perhaps save couple of hours of work for the readers.