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

The $dateFormat protected property is not respected on pivot models #22484

Closed
SonarSoftware opened this issue Dec 19, 2017 · 8 comments
Closed

Comments

@SonarSoftware
Copy link

  • Laravel Version: 5.5.26
  • PHP Version: 7.2
  • Database Driver & Version: Postgres 10

Description:

When using a model to represent a pivot relationship, the protected $dateFormat property is not respected for timestamps on the pivot model.

Steps To Reproduce:

Create two tables (in this case, accounts and services.) Create a pivot table between them (account_service.) Attach as a belongsToMany relationship as below:

return $this->belongsToMany(Service::class) ->using(AccountService::class) ->withTimestamps();

On the pivot model, set protected $dateFormat = "Y-m-d H:i:s.u. Attaching models will now cause a Carbon error, started via this stack trace:

InvalidArgumentException : Data missing /usr/share/sonar/vendor/nesbot/carbon/src/Carbon/Carbon.php:582 /usr/share/sonar/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Concerns/HasAttributes.php:715

However, creating a pivot model directly and setting the account ID and service ID on it will save correctly with the appropriate microsecond precision timestamps.

The 'getDateFormat()' call on line 716 of HasAttributes.php does return the expected $dateFormat set on the pivot model. However, the $value passed in is a standard YYYY-MM-DD HH:mm:ss value.

@kevinruscoe
Copy link
Contributor

How are you storing dates in the database? Using Laravel's default $table->timestamps(); will store them as timestamp fields, like 2018-01-05 13:53:03. There's no millisecond on those fields.

I made a simple demo and managed to get the same error as you, Carbon's moaning because the actual date in the DB doesn't conform to the format you're trying to format it as.

@SonarSoftware
Copy link
Author

I'm storing dates with microseconds (2018-01-05 13:53:03.123456)

@kevinruscoe
Copy link
Contributor

As a timestamp field?

@SonarSoftware
Copy link
Author

Yeah, my migrations look like this for the field:

$table->timestamps(6);

This creates a timestamp field in Postgres with microsecond precision. All my models have a protected $dateFormat value of "Y-m-d H:i:s.u";

@kevinruscoe
Copy link
Contributor

Gotcha. Does all your data in your database conform to that? I've filled up a few tables with just dates like 2018-01-05 14:55:17.107507 and I no longer see that issue. However, if any of them are missing the millisecond, then the error gets thrown (because they don't conform to the format requested).

I also notice that using the factory() method to fill the database doesn't add the right timestamps, so I got that error on the first time around.

@SonarSoftware
Copy link
Author

Yeah, it does. The problem explicitly seems to occur when you attach via a pivot using ->attach - if the pivot table has ->timestamps(6) and you have the $dateFormat set to "Y-m-d H:i:s.u" on the pivot model, it gets ignored during the attach call (at least, in my testing.)

@kevinruscoe
Copy link
Contributor

I've tracked down the issue.

There's a trait that deals with insert records into the pivot table Illuminate\Database\Eloquent\Relations\Concerns\InteractsWithPivotTable.

When using attach() it doesn't check to see if the table is using a model as a representation. It just uses $this->table which is the tables name (such as account_service). It then just passes a carbon instance as the created_at and updated_at. The carbon instances' toString() method doesn't include the milisecond, so that's why the records being inserted without it, and when being parsed it blows up.

@SonarSoftware
Copy link
Author

Awesome, I had tried to track down the root cause and I figured it was something like that, but got lost in the depths of the framework. Appreciate the fix!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants