Skip to content

Commit

Permalink
Merge branch 'pivot-null' into 7.x
Browse files Browse the repository at this point in the history
  • Loading branch information
taylorotwell committed May 11, 2020
2 parents af5c1d2 + ad676c0 commit dce4429
Show file tree
Hide file tree
Showing 3 changed files with 106 additions and 3 deletions.
58 changes: 58 additions & 0 deletions src/Illuminate/Database/Eloquent/Relations/BelongsToMany.php
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,13 @@ class BelongsToMany extends Relation
*/
protected $pivotWhereIns = [];

/**
* Any pivot table restrictions for whereNull clauses.
*
* @var array
*/
protected $pivotWhereNulls = [];

/**
* The default values for the pivot columns.
*
Expand Down Expand Up @@ -504,6 +511,57 @@ public function orWherePivotNotIn($column, $values)
return $this->wherePivotNotIn($column, $values, 'or');
}

/**
* Set a "where null" clause for a pivot table column.
*
* @param string $column
* @param string $boolean
* @param bool $not
* @return $this
*/
public function wherePivotNull($column, $boolean = 'and', $not = false)
{
$this->pivotWhereNulls[] = func_get_args();

return $this->whereNull($this->table.'.'.$column, $boolean, $not);
}

/**
* Set a "where not null" clause for a pivot table column.
*
* @param string $column
* @param string $boolean
* @return $this
*/
public function wherePivotNotNull($column, $boolean = 'and')
{
return $this->wherePivotNull($column, $boolean, true);
}

/**
* Set a "or where null" clause for a pivot table column.
*
* @param string $column
* @param bool $not
* @return $this
*/
public function orWherePivotNull($column, $not = false)
{
return $this->wherePivotNull($column, 'or', $not);
}

/**
* Set a "or where not null" clause for a pivot table column.
*
* @param string $column
* @param bool $not
* @return $this
*/
public function orWherePivotNotNull($column)
{
return $this->orWherePivotNull($column, true);
}

/**
* Find a related model by its primary key or return new instance of the related model.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,10 @@ protected function attachNew(array $records, array $current, $touch = true)
*/
public function updateExistingPivot($id, array $attributes, $touch = true)
{
if ($this->using && empty($this->pivotWheres) && empty($this->pivotWhereIns)) {
if ($this->using &&
empty($this->pivotWheres) &&
empty($this->pivotWhereIns) &&
empty($this->pivotWhereNulls)) {
return $this->updateExistingPivotUsingCustomClass($id, $attributes, $touch);
}

Expand Down Expand Up @@ -409,7 +412,11 @@ public function hasPivotColumn($column)
*/
public function detach($ids = null, $touch = true)
{
if ($this->using && ! empty($ids) && empty($this->pivotWheres) && empty($this->pivotWhereIns)) {
if ($this->using &&
! empty($ids) &&
empty($this->pivotWheres) &&
empty($this->pivotWhereIns) &&
empty($this->pivotWhereNulls)) {
$results = $this->detachUsingCustomClass($ids);
} else {
$query = $this->newPivotQuery();
Expand Down Expand Up @@ -541,6 +548,10 @@ public function newPivotQuery()
call_user_func_array([$query, 'whereIn'], $arguments);
}

foreach ($this->pivotWhereNulls as $arguments) {
call_user_func_array([$query, 'whereNull'], $arguments);
}

return $query->where($this->foreignPivotKey, $this->parent->{$this->parentKey});
}

Expand Down
36 changes: 35 additions & 1 deletion tests/Integration/Database/EloquentBelongsToManyTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ protected function setUp(): void
Schema::create('posts_tags', function (Blueprint $table) {
$table->integer('post_id');
$table->integer('tag_id');
$table->string('flag')->default('');
$table->string('flag')->default('')->nullable();
$table->timestamps();
});

Expand Down Expand Up @@ -765,6 +765,40 @@ public function testOrWherePivotNotInMethod()
$this->assertEquals($relationTags->pluck('id')->toArray(), [$tag1->id, $tag2->id]);
}

public function testWherePivotNullMethod()
{
$tag1 = Tag::create(['name' => Str::random()]);
$tag2 = Tag::create(['name' => Str::random()]);
$post = Post::create(['title' => Str::random()]);

DB::table('posts_tags')->insert([
['post_id' => $post->id, 'tag_id' => $tag1->id, 'flag' => 'foo'],
]);
DB::table('posts_tags')->insert([
['post_id' => $post->id, 'tag_id' => $tag2->id, 'flag' => null],
]);

$relationTag = $post->tagsWithExtraPivot()->wherePivotNull('flag')->first();
$this->assertEquals($relationTag->getAttributes(), $tag2->getAttributes());
}

public function testWherePivotNotNullMethod()
{
$tag1 = Tag::create(['name' => Str::random()]);
$tag2 = Tag::create(['name' => Str::random()]);
$post = Post::create(['title' => Str::random()]);

DB::table('posts_tags')->insert([
['post_id' => $post->id, 'tag_id' => $tag1->id, 'flag' => 'foo'],
]);
DB::table('posts_tags')->insert([
['post_id' => $post->id, 'tag_id' => $tag2->id, 'flag' => null],
]);

$relationTag = $post->tagsWithExtraPivot()->wherePivotNotNull('flag')->first();
$this->assertEquals($relationTag->getAttributes(), $tag1->getAttributes());
}

public function testCanUpdateExistingPivot()
{
$tag = Tag::create(['name' => Str::random()]);
Expand Down

0 comments on commit dce4429

Please sign in to comment.