Home » Php » Human Readable Timestamps Laravel 4 with pivot tables

Human Readable Timestamps Laravel 4 with pivot tables

Posted by: admin November 30, 2017 Leave a comment

Questions:

Is there a way to display the created_at and updated_at timestamps in human readable format if they are used in a pivot table?

Im new to the whole pivot table laravel thing, but right now i am using a pivot table to store user comments on individual posts and each of these have created_at and updated_at timestamps.

If i was just using an ordinary table with a model i would extend my base model which looks like this:

use Carbon\Carbon;

class Base extends Eloquent {

protected function getHumanTimestampAttribute($column)
{
    if ($this->attributes[$column])
    {
        return Carbon::parse($this->attributes[$column])->diffForHumans();
    }

    return null;
}

public function getHumanCreatedAtAttribute()
{
    return $this->getHumanTimestampAttribute("created_at");
}

public function getHumanUpdatedAtAttribute()
{
    return $this->getHumanTimestampAttribute("updated_at");
} 

}

But as im not using a model for the pivot tables how would i work around this? Is there a way i can get these functions to work with my pivot tables? Would using a model for the pivot table be the easiest/correct way to do this?

EDIT
This is what my relation looks like this is placed in my User Model.

/**
 * Guide comments
 *
 * @return mixed
 */

public function guide_comments()
{
    return $this->belongsToMany('Guide', 'guides_comment')->withTimestamps();
}  
Answers:

Imagine we have 2 Models: User and Category with a many-to-many relation, thus having pivot
(category_user: id, user_id, category_id, created_at, updated_at) table to link the 2.

Now, let’s setup the relations like this:

// User model
public function categories()
{
   return $this->belongsToMany('Category')->withTimestamps();
}

// Category model
public function users()
{
   return $this->belongsToMany('User')->withTimestamps();
}

Then, since timestamps are mutated to Carbon objects by default, all you need to do is:

$user = User::with('categories');

$user->categories->first()->pivot->created_at->diffForHumans();

You don’t need custom PivotModel, nor those extra accessors (which are pretty confusing and totally redundant to begin with).


If you want to ease that a bit, you can define accessor like this in fact:

// same for both models
public function getPivotHumansCreatedAtAttribute()
{
    if (is_null($this->pivot)) return null;

    return $this->pivot->created_at->diffForHumans();
}

// then you access it like this:
Category::first()->pivotHumansCreatedAt; // null, since it's not called as relation
User::first()->categories()->first()->pivotHumansCreatedAt; // '2 days ago'

Questions:
Answers:

From Laravel documentation.

http://laravel.com/docs/eloquent#working-with-pivot-tables

Defining A Custom Pivot Model

Laravel also allows you to define a custom Pivot model. To define a custom model, first create your own “Base” model class that extends Eloquent. In your other Eloquent models, extend this custom base model instead of the default Eloquent base. In your base model, add the following function that returns an instance of your custom Pivot model:

 public function newPivot(Model $parent, array $attributes, $table, $exists)
 {
     return new YourCustomPivot($parent, $attributes, $table, $exists);
 }

newPivot function should return the instance of “ class and that class itself inherited from the Illuminate\Database\Eloquent\Model class. Since Eloquent is just a alias to Illuminate\Database\Eloquent\Model, I think following should work.

class YourCustomPivot extends Illuminate\Database\Eloquent\Relations\Pivot {

protected function getHumanTimestampAttribute($column)
{
    if ($this->attributes[$column])
    {
        return Carbon::parse($this->attributes[$column])->diffForHumans();
    }

    return null;
}

public function getHumanCreatedAtAttribute()
{
    return $this->getHumanTimestampAttribute("created_at");
}

public function getHumanUpdatedAtAttribute()
{
    return $this->getHumanTimestampAttribute("updated_at");
} 

}

Now modify your Base class.

class Base extends Eloquent {
     public function newPivot(Model $parent, array $attributes, $table, $exists)
     {
         return new YourCustomPivot($parent, $attributes, $table, $exists);
     }

}

Questions:
Answers:

try it in PHP:

$date = '2014-04-30 19:49:36';  //date returned from DB

echo date("H:i:s",strtotime(str_replace('/','-',$date)));     // 19:49:36
echo date("Y/m/d",strtotime(str_replace('/','-',$date)));     // 2014/04/30

for format check:
http://www.php.net/manual/en/datetime.formats.date.php