Laravel/Eloquent collitions with model traits

Viewed 564

I am using laravel 5.8 for my project, and i am getting the error Bad call Call to undefined method Illuminate\Database\Eloquent\Builder::withSum() because I removed LaravelSubQueryTrait in my traits. When i re-add LaravelSubQueryTrait, my project does not run, I am getting this error Trait method newBaseQueryBuilder has not been applied, because there are collisions with other trait methods on App\Traits\TestModelTrait. Upgrading to laravel 8.x is not an option at this point and I don't quite understand what I am doing wrong. Any tips/advise/ resources to read will be highly appreciated to help solve my problem. Thanks

My TestmodelTrait is as below :

use Alexmg86\LaravelSubQuery\Traits\LaravelSubQueryTrait;
use Carbon\Carbon;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Support\Str;
use Watson\Rememberable\Rememberable;

trait MedyqModelTrait
{
    protected static $skipUuid = false;

    use MedyqTrait, SoftDeletes, Rememberable, LaravelSubQueryTrait;

    protected static function boot()
    {
        parent::boot();

        self::creating(function ($record) {

            if (!self::$skipUuid) {
                $record->{'uuid'} = (string)Str::orderedUuid();
            }

            if (auth()->check()) {
                $record->{'created_by'} = auth()->id();
                $record->{'updated_by'} = auth()->id();
            }
        });

        self::updating(function ($record) {

            if (auth()->check()) {
                $record->{'updated_by'} = auth()->id();
            }

        });

        self::updated(function ($record) {

            $record->flushCache();

        });

        self::deleted(function ($record) {

            if (auth()->check()) {

                $record->{'deleted_by'} = auth()->id();

                $record->save();
            }

        });

        self::restored(function ($record) {

            if (auth()->check()) {

                $record->{'restored_by'} = auth()->id();

                $record->{'restored_at'} = Carbon::now();

                $record->save();
            }

        });
    }

    /**
     * Get the route key for the model.
     *
     * @return string
     */
    public function getRouteKeyName()
    {
        return 'uuid';
    }

    public function scopeAlive($query)
    {
        $query->where("status", config("constants.status.alive"));
    }

}

My TestTrait looks like this :

use App\Entities\User;
use Carbon\Carbon;
use Exception;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Str;

trait MedyqTrait
{
    public static function getTableName()
    {
        return with(new static)->getTable();
    }

    public function scopeActive($query)
    {
        $query->where("status", config("constants.status.active"));
    }

    public function scopeInActive($query)
    {
        $query->where("status", config("constants.status.inactive"));
    }

    /**
     * Mass (bulk) insert for Postgres Laravel 5
     *
     * insert([
     *   ['id'=>1,'value'=>10],
     *   ['id'=>2,'value'=>60]
     * ]);
     *
     *
     * @param array $rows
     * @param null $table
     * @param bool $skipUUid
     * @param bool $timestamps
     * @param bool $authorstamp
     * @return bool
     * @throws Exception
     */
    public function bulkInsert(array $rows, $table = null, $skipUUid = false, $timestamps = true, $authorstamp = true)
    {
        $return_values = array_filter($rows, 'is_array');
        if (!count($return_values) > 0) {
            throw new Exception("This function expects a multidimensional associative array");
        }

        if (is_null($table)) {
            $table = DB::getTablePrefix() . $this->getTable();
        }

        $rows = array_map(function ($item) use ($skipUUid, $timestamps, $authorstamp) {
            $authenticated = auth()->check();
            $authorId = auth()->id();
            $time = Carbon::now();
            if (!$skipUUid) {
                $item['uuid'] = Str::orderedUuid();
            }
            if ($timestamps && !key_exists('created_by', $item) && $authenticated && $authorstamp) {
                $item['created_by'] = $authorId;
            }
            if ($timestamps && !key_exists('updated_by', $item) && $authenticated && $authorstamp) {
                $item['updated_by'] = $authorId;
            }
            if ($timestamps && !key_exists('created_at', $item)) {
                $item['created_at'] = $time;
            }
            if ($timestamps && !key_exists('updated_at', $item)) {
                $item['updated_at'] = $time;
            }
            return $item;
        }, $rows);

        $first = reset($rows);

        $columns = implode(',',
            array_map(function ($value) {
                return "$value";
            }, array_keys($first))
        );

        $values = implode(',', array_map(function ($row) {
                return '(' . implode(',',
                        array_map(function ($value) {
                            return "'" . str_replace("'", "''", $value) . "'";
                        }, $row)
                    ) . ')';
            }, $rows)
        );


        $sql = "INSERT INTO {$table}({$columns}) VALUES {$values}";

        return DB::statement($sql);
    }

    public function deletedBy()
    {
        return $this->belongsTo(User::class, "deleted_by", "id");
    }
}
2 Answers

Guess you have problem with the syntax.

$invoice = Invoice::where('id', $invoice->id)
    ->with('items')
    ->withSum('items', 'total_amount')
    ->withSum('items', 'amount_paid')
    ->first();

withSum is probably available only since Laravel version 8.x, before that I think only withCount was available. But if you still want to use withSum in earlier version you can define a macro'

You could also try use LaravelSubQueryTrait trait directly in the model/models.

use Alexmg86\LaravelSubQuery\Traits\LaravelSubQueryTrait;
use Illuminate\Database\Eloquent\Model;

class Invoice extends Model
{
    use LaravelSubQueryTrait;

Reference https://github.com/Alexmg86/laravel-sub-query

Related