iT邦幫忙

1

Laravel 報錯!TypeError: Argument 1 passed to App/Models/Category::scopeRoots() must be an instance

請教前輩大大!我的Laravel 練習作業中,資料庫中有資料如下圖:
https://ithelp.ithome.com.tw/upload/images/20200321/201217546T0LucnsQI.png
作業中有: Category.php 內容如下:

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class Category extends Model
{
    protected $fillable = ['name', 'slug', 'order', 'parent_id'];

    public function children()
    {
    	return $this->hasMany(self::class, 'parent_id');
    }

    public function parent()
    {
    	return $this->belongsTo(self::class, 'parent_id');
    }

    public function scopeRoots(Builder $builder)
    {
    	$builder->whereNull('parent_id');
    }

    public function scopeSort(Builder $builder, $direction = 'asc')
    {
    	$builder->oredrBy('order', $direction);
    }
}

使用 tinker 查詢資料庫時,Category::all() 能正常輸出,但 執行Category::roots()->get() 時卻報錯 如下:

TypeError: Argument 1 passed to App/Models/Category::scopeRoots() must be an instance of App/Models/Builder, instance of Illuminate/Database/Eloquent/Builder given, called in D:/xampp/htdocs/webs/mart/mart-server/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Builder.php on line 978

有勞大大看看我到底應該如何修復這個錯誤。預先謝謝您的熱情幫助,謝謝!

甲土豆 iT邦新手 5 級 ‧ 2020-03-23 09:57:36 檢舉
你的標題字打錯了 ,是Laravel
啊!對耶,老是手殘 真不好意思。
趕快...,標題修改了!
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

2 個回答

0
dominwong5
iT邦見習生 ‧ 2020-03-22 02:19:00
最佳解答

scope用錯了? 你是laravel幾?
https://laravel.com/docs/5.8/eloquent#local-scopes

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class User extends Model
{
    /**
     * Scope a query to only include popular users.
     *
     * @param  \Illuminate\Database\Eloquent\Builder  $query
     * @return \Illuminate\Database\Eloquent\Builder
     */
    public function scopePopular($query)
    {
        return $query->where('votes', '>', 100);
    }

    /**
     * Scope a query to only include active users.
     *
     * @param  \Illuminate\Database\Eloquent\Builder  $query
     * @return \Illuminate\Database\Eloquent\Builder
     */
    public function scopeActive($query)
    {
        return $query->where('active', 1);
    }
}

用要return query builder吧 你的方法沒有return

我的版本是:laravel 6.18.2
謝謝您熱情的幫助,最後我獲得的答案是:
在我的Category.php 中 use 一下 Builder 就正常了,我自己到現在也還有點迷惘,還需要多加練習。我最後的程式碼可檢視如下方。

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

use Illuminate\Database\Eloquent\Builder;


class Category extends Model
{
    protected $fillable = ['name', 'slug', 'order', 'parent_id'];

    public function children()
    {
    	return $this->hasMany(self::class, 'parent_id');
    }

    public function parent()
    {
    	return $this->belongsTo(self::class, 'parent_id');
    }

    public function scopeRoots(Builder $builder)
    {
    	$builder->whereNull('parent_id');
    }

    public function scopeSort(Builder $builder, $direction = 'asc')
    {
    	$builder->orderBy('order', $direction);
    }
}

1
小魚
iT邦大師 1 級 ‧ 2020-03-22 09:41:43

話說我怎麼沒看到root,
另外他意思好像是說scopeRoots的括號裡面應該要有一個參數,
但是你沒有給他參數.

謝謝 @小魚 熱心解惑!

 public function scopeRoots(Builder $builder)
    {
    	$builder->whereNull('parent_id');
    }

我依照自己所學過的知識點,以為scopeRoots 可以 依照依賴注入的方式獲得參數 $builder 所以定義了 select * from categories where 'parent_id, '=', 'null' 以便獲取 '父級分類',只是一直發生錯誤。
後來,我嘗試使用dump $builder 發現 結果是 Unknown target: $builder
所以我就再嘗試 use 一下 Builder 結果,就神奇地好了。
我還一頭霧水中,如果可以指出一些相關優質文章。將會無限感激。

我要發表回答

立即登入回答