How to fix it Call to a member function diffForHumans() on string in laravel 5.3

Raka Hikmah picture Raka Hikmah · Aug 10, 2017 · Viewed 11.9k times · Source

Why when I use query builder instead there is an error on the function diffForHumans (), but if I use ELoquent ROM but no error there is a way to overcome it? (How can i fix it) thank you

diffForHumans()

this is ArticlesController.php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Article;
use Carbon\Carbon;
use Auth;
use DB;

class ArticlesController extends Controller
{

    public function index()
    {
        $articles =DB::table('articles')->get();
        $articles = ['articles'=>$articles];
        return view('articles.index',$articles);
    }
}

this is model Article.php

<?php

namespace App;

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

class Article extends Model
{
    //
    use SoftDeletes ;

    protected $fillable = [
        'user_id','content','live','post_on',
    ];

    protected $dates =[
        'post_on','deleted_at','created_at','updated_at',
    ];

    public function setLiveAttribute($value)
    {
        $this->attributes['live'] = (boolean)($value);
    }

    public function getShortContentAttribute()
    {
        return substr($this->content,0,random_int(60,150))."...";
    }

    public function setPostOnAttribute($value)
    {
        $this->attributes['post_on'] = Carbon::parse($value);
    }

    public function setCreatedAtAttribute($value)
    {
        $this->attributes['post_on'] = Carbon::parse($value);
    }



}

and that is my code, how i can fix it? thank you

Answer

yoeunes picture yoeunes · Aug 10, 2017

i noticed a couple of things in you're code,

  • no need to cast created_at and updated_at to dates, they are already casted and are instances of Carbon
  • you can use the property $casts to cast simple attributs like live
  • no need to add a mutator for post_on date because you add it to $dates
  • also you set a mutator on created_at instead of post_on, you use SetCreatedAttribute instead of setPostOnAttribute
  • instead of substr($this->content,0,random_int(60,150))."..." you can use str_limit helper function of Laravel, also change random_int to rand => int rand ( int $min , int $max )

the query builder return dates as strings, you need to parse before using them or you will get an error like this one PHP error: Call to a member function on string, just do it like this :

\Carbon\Carbon::parse(\DB::table('articles')->first()->post_on)->diffForHumans()

you can make your model simpler like this :

<?php

namespace App;

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

class Article extends Model
{
    use SoftDeletes ;

    protected $fillable = [
        'user_id','content','live','post_on',
    ];

    protected $dates = [
        'post_on','deleted_at'
    ];

    protected $casts = [
        'live'  => 'boolean'
    ];

    public function getShortContentAttribute()
    {
        return str_limit($this->content, rand(60,150));
    }
}

also you can simplify you index method like this :

public function index()
{
    $articles = DB::table('articles')->get();

    return view('articles.index', compact('articles'));
}