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

2

8

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

Homochromatic answered 10/8, 2017 at 17:46 Comment(0)
N
14

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'));
}
Necropsy answered 10/8, 2017 at 18:17 Comment(1)
ouh thank you this is good suggestion, and when i try your suggestions it worksHomochromatic
A
7

By default eloquent returns date/time fields as a Carbon instance, where query builder don't. So if you want to use Carbon on query builder's returned property, you have to wrap the property with Carbon::parse() method.

For example, I can use one of Carbon's method toCookieString() on a eloquent result such as

echo App\User::find(1)->created_at->toCookieString();

which will give a response like this Thursday, 10-Aug-2017 17:59:53 UTC. But if I use query builder instead such as

echo DB::table('users')->find(1)->created_at->toCookieString();

then it will give an error

Call to a member function toCookieString() on string

To use Carbon in here I have wrap the property with Carbon's parse() method.

echo Carbon\Carbon::parse(DB::table('users')->find(1)->created_at)->toCookieString();

This will give the desired result as eloquent.

Arela answered 10/8, 2017 at 18:20 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.