3
votes

I've created a few datetime fields in my database, and as is described in Laravel documentation, I can "customize which fields are automatically mutated". However there's no example showing how it can be done, nor is there any search result. What should I do to make certain fields auto mutate?

For example, I created a table called "people" in migration, one of the fields is defined as this:

class CreatePeopleTable extends Migration {
  public function up(){
    Schema::create("bookings",function($table){
      ...
      $table->dateTime("birthday");
      ...
    }
  }
}

And I defined a model for "people" in models:

class People extends Eloquent{
  //nothing here
}

If I refer to the birthday of a People instance, it'll be string, instead of DateTime

$one=People::find(1);
var_dump($one->birthday);
//String

The date mutator should be able to convert it directly to Carbon object, but the documentation doesn't say much about how it should be implemented.

4

4 Answers

17
votes

In your People model just add this array:

protected $dates = array('birthday');

Laravel's Model.php internaly merges your fields with the default ones like this:

/**
     * Get the attributes that should be converted to dates.
     *
     * @return array
     */
    public function getDates()
    {
        $defaults = array(static::CREATED_AT, static::UPDATED_AT, static::DELETED_AT);

        return array_merge($this->dates, $defaults);
    }
5
votes

According to this doc, you can use model member function getDates() to customize which fileds are automatically mutated, so the following example will return Carbon instance instead of String:

$one = People::find(1);
var_dump($one->created_at);//created_at is a field mutated by default
//Carbon, which is a subclass of Datetime

But it doesn't say clearly how to add your own fields. I found out that the getDates() method returns an array of strings:

$one = People::find(1);
echo $one->getDates();
//["created_at","modified_at"]

So what you can do is appending field names to the return value of this method:

class People extends Eloquent{
    public function getDates(){
        $res=parent::getDates();
        array_push($res,"birthday");
        return $res;
    }
}

Now birthday field will be returned as a Carbon instance whenever you call it:

$one = People::find(1);
var_dump($one->birthday);
//Carbon
3
votes

What do you mean by: automatically mutated?

If you mean mutated after being retrieved from DB use Accessors and Mutators (Laravel docs).

Add this to your model:

public function getDateAttribute( $date )
{
     // modify $date as you want, example
     // $date = new \Carbon\Carbon($date);
     // $date->addDay()
     // return (string)$date
}
1
votes

As Sasa Tokic says, add protected $dates = array('birthday'); to your People model like so:

class People extends Eloquent{
    protected $dates = array('birthday');
}

You can then use Carbon to do clever things to this value, like so:

$people->birthday->format('jS F Y')

PHP's date() function docs (http://uk3.php.net/manual/en/function.date.php) and Carbon's docs (https://github.com/briannesbitt/Carbon) will help here: