diff --git a/src/Illuminate/Database/Eloquent/Relations/BelongsToMany.php b/src/Illuminate/Database/Eloquent/Relations/BelongsToMany.php index 7011337af61c..61565ba4e214 100755 --- a/src/Illuminate/Database/Eloquent/Relations/BelongsToMany.php +++ b/src/Illuminate/Database/Eloquent/Relations/BelongsToMany.php @@ -75,6 +75,13 @@ class BelongsToMany extends Relation */ protected $pivotWhereIns = []; + /** + * Default values for the pivot columns. + * + * @var array + */ + protected $pivotValues = []; + /** * Indicates if timestamps are available on the pivot table. * @@ -347,6 +354,32 @@ public function orWherePivot($column, $operator = null, $value = null) return $this->wherePivot($column, $operator, $value, 'or'); } + /** + * Sets default value when querying or creating a new row in the pivot table. + * + * @param string $column + * @param mixed $value + * @return \Illuminate\Database\Eloquent\Relations\BelongsToMany + */ + public function withPivotValues($column, $value = null) + { + if (is_array($column)) { + foreach ($column as $name => $value) { + $this->withPivotValues($name, $value); + } + + return $this; + } + + if (is_null($value)) { + throw new \InvalidArgumentException('$value cannot be null.'); + } + + $this->pivotValues[] = func_get_args(); + + return $this->wherePivot($column, '=', $value); + } + /** * Set an "or where in" clause for a pivot table column. * diff --git a/src/Illuminate/Database/Eloquent/Relations/Concerns/InteractsWithPivotTable.php b/src/Illuminate/Database/Eloquent/Relations/Concerns/InteractsWithPivotTable.php index e5aaf533c53b..952f34005ad8 100644 --- a/src/Illuminate/Database/Eloquent/Relations/Concerns/InteractsWithPivotTable.php +++ b/src/Illuminate/Database/Eloquent/Relations/Concerns/InteractsWithPivotTable.php @@ -300,6 +300,12 @@ protected function baseAttachRecord($id, $timed) $record = $this->addTimestampsToAttachment($record); } + // Adding the default pivot values (if there is any) to the record. + foreach ($this->pivotValues as $arguments) { + list($name, $value) = $arguments; + $record[$name] = $value; + } + return $record; } diff --git a/tests/Database/DatabaseEloquentBelongsToManyWithDefaultAttributesTest.php b/tests/Database/DatabaseEloquentBelongsToManyWithDefaultAttributesTest.php new file mode 100644 index 000000000000..8ccec406d66b --- /dev/null +++ b/tests/Database/DatabaseEloquentBelongsToManyWithDefaultAttributesTest.php @@ -0,0 +1,56 @@ +getMockBuilder('Illuminate\Database\Eloquent\Relations\BelongsToMany')->setMethods(['touchIfTouching'])->setConstructorArgs($this->getRelationArguments())->getMock(); + $relation->withPivotValues(['is_admin' => 1]); + } + + public function testWithPivotValuesMethodSetsDefaultArgumentsForInsertion() + { + $relation = $this->getMockBuilder('Illuminate\Database\Eloquent\Relations\BelongsToMany')->setMethods(['touchIfTouching'])->setConstructorArgs($this->getRelationArguments())->getMock(); + $relation->withPivotValues(['is_admin' => 1]); + + $query = m::mock('stdClass'); + $query->shouldReceive('from')->once()->with('club_user')->andReturn($query); + $query->shouldReceive('insert')->once()->with([['club_id' => 1, 'user_id' => 1, 'is_admin' => 1]])->andReturn(true); + $relation->getQuery()->shouldReceive('getQuery')->andReturn($mockQueryBuilder = m::mock('stdClass')); + $mockQueryBuilder->shouldReceive('newQuery')->once()->andReturn($query); + + $relation->attach(1); + } + + public function getRelationArguments() + { + $parent = m::mock('Illuminate\Database\Eloquent\Model'); + $parent->shouldReceive('getKey')->andReturn(1); + $parent->shouldReceive('getCreatedAtColumn')->andReturn('created_at'); + $parent->shouldReceive('getUpdatedAtColumn')->andReturn('updated_at'); + $parent->shouldReceive('getAttribute')->with('id')->andReturn(1); + + $builder = m::mock('Illuminate\Database\Eloquent\Builder'); + $related = m::mock('Illuminate\Database\Eloquent\Model'); + $builder->shouldReceive('getModel')->andReturn($related); + + $related->shouldReceive('getTable')->andReturn('users'); + $related->shouldReceive('getKeyName')->andReturn('id'); + + $builder->shouldReceive('join')->once()->with('club_user', 'users.id', '=', 'club_user.user_id'); + $builder->shouldReceive('where')->once()->with('club_user.club_id', '=', 1); + $builder->shouldReceive('where')->once()->with('club_user.is_admin', '=', 1, 'and'); + + return [$builder, $parent, 'club_user', 'club_id', 'user_id', 'id', 'id', null, false]; + } +}