Laravel-mongodb: Carbon/DateTime is not being converted when I save it in an array

Created on 27 Jul 2017  路  6Comments  路  Source: jenssegers/laravel-mongodb

Hi,

So my problem is that a Carbon date is not automatically converted to a MongoDate (like it says in the docs) if I store that date inside an array.

My code is this:

$product->stock = [
    'amount'       => $amount,
    'lastUpdate' => Carbon::now(),
];

$product->save();

and I get this on my document for the lastUpdate field:

lastUpdate:Object
date:"2017-07-27 09:42:00.000000"
timezone_type:3
timezone:"UTC"

It works just fine if I do this:

'lastUpdate' => new \MongoDB\BSON\UTCDateTime(new \DateTime('now'))

becomes:

lastUpdate:2017-07-27 11:49:47.000

The documentation says that my code should work:

Eloquent allows you to work with Carbon/DateTime objects instead of MongoDate objects. Internally, these dates will be converted to MongoDate objects when saved to the database. If you wish to use this functionality on non-default date fields you will need to manually specify them as described here: http://laravel.com/docs/eloquent#date-mutators

and it actually does... but not inside an array.

By the way, I also defined this:

    protected $dates = [
        'stock.lastUpdate',
    ];

So is this a bug? Or I am doing something wrong?

enhancement question Needs investigation

Most helpful comment

I seem solved this problem.It's very useful to add a data attribute.
This is my model file

<?php

namespace Modules\Project\Entities;

use Jenssegers\Mongodb\Eloquent\Model;
use Jenssegers\Mongodb\Eloquent\SoftDeletes;

//use Illuminate\Database\Eloquent\Model;
//use Illuminate\Database\Eloquent\SoftDeletes;

class Project extends Model
{
    protected $connection = 'mongodb';

    use SoftDeletes;

    protected $dates = ['start_date_at', 'online_date_at'];

}

All 6 comments

so do i.
when i use Carbon:now() for created_at,It will save a array just like:
created_at: [ "date" => "2018-01-11 15:49:21.000000", "timezone_type" => 3, "timezone" => "PRC", ],
in fact, I want to save a MongoDate to it.

How to define $dates attribute for array of documents. For example I want following structure.

versions => [
  [
    updated_at => 'some date',
    created_at => 'some_date'
  ],
  [
    updated_at => 'some date',
    created_at => 'some_date'
  ],
]

Is there any way to achieve this without explicitly converting date like below

versions => [
  [
    updated_at => new \MongoDB\BSON\UTCDateTime(new \DateTime('now')),
    created_at => new \MongoDB\BSON\UTCDateTime(new \DateTime('now'))'
  ],
  [
    updated_at => new \MongoDB\BSON\UTCDateTime(new \DateTime('now'))',
    created_at => new \MongoDB\BSON\UTCDateTime(new \DateTime('now'))
  ],
]

I seem solved this problem.It's very useful to add a data attribute.
This is my model file

<?php

namespace Modules\Project\Entities;

use Jenssegers\Mongodb\Eloquent\Model;
use Jenssegers\Mongodb\Eloquent\SoftDeletes;

//use Illuminate\Database\Eloquent\Model;
//use Illuminate\Database\Eloquent\SoftDeletes;

class Project extends Model
{
    protected $connection = 'mongodb';

    use SoftDeletes;

    protected $dates = ['start_date_at', 'online_date_at'];

}

How to define $dates attribute for array of documents. For example I want following structure.

versions => [
  [
    updated_at => 'some date',
    created_at => 'some_date'
  ],
  [
    updated_at => 'some date',
    created_at => 'some_date'
  ],
]

Is there any way to achieve this without explicitly converting date like below

versions => [
  [
    updated_at => new \MongoDB\BSON\UTCDateTime(new \DateTime('now')),
    created_at => new \MongoDB\BSON\UTCDateTime(new \DateTime('now'))'
  ],
  [
    updated_at => new \MongoDB\BSON\UTCDateTime(new \DateTime('now'))',
    created_at => new \MongoDB\BSON\UTCDateTime(new \DateTime('now'))
  ],
]

Hey, did you get the solution for such attributes? I am also facing the same

"history" : [
{
"action" : "initiate",
"offer_price" : 450000.0,
"action_by" : "buyer",
"action_date" : ISODate("2021-03-12T06:20:51.000Z")
},
{
"action" : "counter",
"offer_price" : 470000.0,
"action_by" : "seller",
"action_date" : ISODate("2021-03-12T06:22:18.000Z")
},

How can I define action_date?

+1 - no matter what I do, only created_at and inserted_at are saved as strings.

I solved my problem creating a new model for the child object...

class ArticleReport extends Model
{
    protected $collection = 'articleReports';
    public function reports(){
        return $this->embedsMany(FlagReport::class);
    }    
}

class FlagReport extends Model {
    protected $primaryKey = null; //Remove id
    protected $dates = [
        "datetime"
    ];
}

Then, I can use it like this:

$report = new ArticleReport();

$flagReport = new FlagReport();
$flagReport->userId = $userId;
$flagReport->flag = $flag;
$flagReport->datetime = Carbon::now();

$report->reports()->associate($flagReport);

$report->save();
Was this page helpful?
0 / 5 - 0 ratings

Related issues

naveedyasin picture naveedyasin  路  3Comments

pirmax picture pirmax  路  3Comments

phuocduy1988 picture phuocduy1988  路  3Comments

geofflancaster picture geofflancaster  路  3Comments

viacheslavpleshkov picture viacheslavpleshkov  路  3Comments