Skip to content

Instantly share code, notes, and snippets.

@half2me
Created July 7, 2016 12:34
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save half2me/2b4d9d97130a06692bb70fcd6c7a603e to your computer and use it in GitHub Desktop.
Save half2me/2b4d9d97130a06692bb70fcd6c7a603e to your computer and use it in GitHub Desktop.
Inner JOIN bug in CakePHP
<?php
// So I'm going to be demonstrating a problem with INNER joins
//Bake automatically creates INNER JOINs for a belongsTo association,
// where the foreign key is not allowed to be null (Always BelongsTo)
// This is great if you have an (AlwaysBelongsTo) association, but
// when you don't always BelongTo another model, we need LEFT joins.
// The problem arised when you have a model that someTimesBelongsTo another model
// and that other model alwaysBelongsTo another model (LEFT, then INNER joins)
// Cake doesn't use proper parenthesis in these cases, but simply lines the joins up,
// one after another.
// Let me show you the following scenario
// Comments someTimesBelongsTo Articles (Lets say we can have stray comments) // LEFT JOIN here
// Articles alwaysBelongsTo Authors // INNER JOIN here
// CommentsTable.php
public function initialize(array $config)
{
// ...
$this->belongsTo('Articles', [
'joinType' => 'INNER'
]);
//...
}
// ArticlesTable.php
public function initialize(array $config)
{
// ...
$this->belongsTo('Authors', [
'joinType' => 'LEFT' // Or just leave this blank, I think LEFT joins are the default
]);
//...
}
// Now lets try the following code in our CommentsController.php
// Note that if we run this with an empty Articles and Authors table, it will still work fine
// Only thing we will notice, is that our entity will have a $entity->articles field set to null
$this->Comments->find()
->contain(['Articles']);
// Now lets try it this way:
$this->Comments->find()
->contain(['Articles', 'Articles.Authors']); // since we want to not only have articles, but their authors as well
// This works fine, if there are authors in the system, but try it when there are no authors. It will return an empty result.
// Not just an empty articles association, but it won't find any comments, because its doing an INNER JOIN.
// Of course if change the strategy to use a separate query that will work, but joining should work as well. I would suggest
// the proper use of parenthesis in such situations.
?>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment