Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[5.2] firstOrCreate will not create new db rows when a model has a mutator #14656

Merged
merged 9 commits into from
Aug 12, 2016
4 changes: 4 additions & 0 deletions src/Illuminate/Database/Eloquent/Builder.php
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,8 @@ public function findOrNew($id, $columns = ['*'])
*/
public function firstOrNew(array $attributes)
{
$attributes = $this->model->newInstance()->fill($attributes)->attributesToArray();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wouldn't fill() only works if we un-guard the model?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes if someone tries to use variables that aren't fillable, but if that's the case it should not create a new model anyway because those attributes are guarded

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not create a new model anyway because those attributes are guarded

Mass assignment exception doesn't occur when you call save(), it occur within fill() https://github.com/laravel/framework/blob/5.2/src/Illuminate/Database/Eloquent/Model.php#L439-L457

You might want to look at forceFill().

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See the newest commit. Instead of forceFill() I just moved the instance line to the top of the method
$instance = $this->model->newInstance($attributes);
This was already in the method beforehand so it should not change the behavior of the method and still fix the bug that was reported.


if (! is_null($instance = $this->where($attributes)->first())) {
return $instance;
}
Expand All @@ -248,6 +250,8 @@ public function firstOrNew(array $attributes)
*/
public function firstOrCreate(array $attributes)
{
$attributes = $this->model->newInstance()->fill($attributes)->attributesToArray();

if (! is_null($instance = $this->where($attributes)->first())) {
return $instance;
}
Expand Down
4 changes: 4 additions & 0 deletions src/Illuminate/Database/Eloquent/Relations/BelongsToMany.php
Original file line number Diff line number Diff line change
Expand Up @@ -707,6 +707,8 @@ public function findOrNew($id, $columns = ['*'])
*/
public function firstOrNew(array $attributes)
{
$attributes = $this->getParent()->newInstance()->fill($attributes)->attributesToArray();

if (is_null($instance = $this->where($attributes)->first())) {
$instance = $this->related->newInstance($attributes);
}
Expand All @@ -724,6 +726,8 @@ public function firstOrNew(array $attributes)
*/
public function firstOrCreate(array $attributes, array $joining = [], $touch = true)
{
$attributes = $this->getParent()->newInstance()->fill($attributes)->attributesToArray();

if (is_null($instance = $this->where($attributes)->first())) {
$instance = $this->create($attributes, $joining, $touch);
}
Expand Down
4 changes: 4 additions & 0 deletions src/Illuminate/Database/Eloquent/Relations/HasOneOrMany.php
Original file line number Diff line number Diff line change
Expand Up @@ -266,6 +266,8 @@ public function findOrNew($id, $columns = ['*'])
*/
public function firstOrNew(array $attributes)
{
$attributes = $this->getParent()->newInstance()->fill($attributes)->attributesToArray();

if (is_null($instance = $this->where($attributes)->first())) {
$instance = $this->related->newInstance($attributes);

Expand All @@ -283,6 +285,8 @@ public function firstOrNew(array $attributes)
*/
public function firstOrCreate(array $attributes)
{
$attributes = $this->getParent()->newInstance()->fill($attributes)->attributesToArray();

if (is_null($instance = $this->where($attributes)->first())) {
$instance = $this->create($attributes);
}
Expand Down
4 changes: 4 additions & 0 deletions src/Illuminate/Database/Eloquent/Relations/MorphOneOrMany.php
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,8 @@ public function findOrNew($id, $columns = ['*'])
*/
public function firstOrNew(array $attributes)
{
$attributes = $this->getParent()->newInstance()->fill($attributes)->attributesToArray();

if (is_null($instance = $this->where($attributes)->first())) {
$instance = $this->related->newInstance($attributes);

Expand All @@ -144,6 +146,8 @@ public function firstOrNew(array $attributes)
*/
public function firstOrCreate(array $attributes)
{
$attributes = $this->getParent()->newInstance()->fill($attributes)->attributesToArray();

if (is_null($instance = $this->where($attributes)->first())) {
$instance = $this->create($attributes);
}
Expand Down