How to use computed value as if it is a column value in a Laravel model?

I have a project with a project model that looks like this:

class Product extends Model
{
    public $timestamps = true;
    protected $guarded = ['id'];
    protected $table = 'products';
    protected $hidden = ['created_at', 'updated_at'];
    protected $fillable = ['name', 'category_id', 'units', 'b_price', 's_price', 'warn_count', 'added_by'];

    public function category()
    {
        return $this->belongsTo('App\Category');
    }

    public function stock(){
        $product_id = $this->id;
        $filter = ['product_id' => $product_id];
        //STOCK PLUS
        //credit purchases
        $cr_purchases = CreditPurchase::where($filter)->sum('qty');
        //purchases
        $purchases = Purchase::where($filter)->sum('qty');
        //returns in
        $re_in = ReturnIn::where($filter)->sum('qty');
        //STOCK MINUS
        //credit sales
        $cr_sales = CreditSale::where($filter)->sum('qty');
        //sales
        $sales = Sale::where($filter)->sum('qty');
        //returns out
        $re_out = ReturnOut::where($filter)->sum('qty');
        //damaged
        $damaged = DamagedProduct::where($filter)->sum('qty');
        return $cr_purchases + $purchases + $re_in - ($cr_sales + $sales + $re_out + $damaged);
    }
}

As you can see, stocks represent the estimated value for each model. I want to make queries based on this, as if it were a column of a product table.

+4
source share
2 answers

Method 1
Change the stock method as an activator of the Laravel model.

public function getStockAttribute(){
   //code logic
}

Get the results in the form of a collection and perform filtering in the "warehouse"; attribute
I would do something like.

Products::where('product','like','miraa') //where
->get()
->filter(function($item) {
    return $item->stock > 100;
});

Learn more about filtering collections.

2
. scopes laravel.

public function scopeAvailbaleStock($query, $type)
{
    return $query->where('type', $type);
    // could perform filters here for the query above
}

$users = Products::available_stock()->get();

3 jarektkaczyk/eloquence

public function scopeWhereStock($query, $price, $operator = '=', $bool = 'and'){
    $query->where('info1', $operator, $price, $bool);
   }

// then
Products::whereStock(25); // where('info1', 25);
Products::whereStcok(25, '>'); // where('info1', '>', 25);
Products::whereStock(25, '=', 'or'); // orWhere('info1', 25);

Howerever, 1 2. , ,

+1

, $appends . :

class Product extends Model
{
    public $timestamps = true;
    protected $guarded = ['id'];
    protected $table = 'products';
    protected $hidden = ['created_at', 'updated_at'];
    protected $fillable = ['name', 'category_id', 'units', 'b_price', 's_price', 'warn_count', 'added_by'];
    protected $appends = ['stock'];

    public function category()
    {
        return $this->belongsTo('App\Category');
    }

    public function getStockAttribute(){
        $product_id = $this->id;
        $filter = ['product_id' => $product_id];
        //STOCK PLUS
        //credit purchases
        $cr_purchases = CreditPurchase::where($filter)->sum('qty');
        //purchases
        $purchases = Purchase::where($filter)->sum('qty');
        //returns in
        $re_in = ReturnIn::where($filter)->sum('qty');
        //STOCK MINUS
        //credit sales
        $cr_sales = CreditSale::where($filter)->sum('qty');
        //sales
        $sales = Sale::where($filter)->sum('qty');
        //returns out
        $re_out = ReturnOut::where($filter)->sum('qty');
        //damaged
        $damaged = DamagedProduct::where($filter)->sum('qty');
        return $cr_purchases + $purchases + $re_in - ($cr_sales + $sales + $re_out + $damaged);
    }
}

@samueldervis. : http://laraveldaily.com/why-use-appends-with-accessors-in-eloquent/

0

Source: https://habr.com/ru/post/1653826/


All Articles