Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Human Readable Timestamps Laravel 4 with pivot tables

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();
}  
like image 479
jackthedev Avatar asked May 12 '14 22:05

jackthedev


3 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'
like image 138
Jarek Tkaczyk Avatar answered Nov 10 '22 05:11

Jarek Tkaczyk


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);
     }

}
like image 2
tharumax Avatar answered Nov 10 '22 06:11

tharumax


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

like image 1
mwafi Avatar answered Nov 10 '22 04:11

mwafi