Skip to content

Codulab/laravel-computed-properties

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

18 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Computed properties for Eloquent

Code quality Latest Version on Packagist Licence Build Status

Laravel 5.4+

Based on this tweet: https://twitter.com/reinink/status/899713609722449920

Some examples for better understanding of this power:

class Order extends Model
{
    use ComputedProperties;

    public function products()
    {
        return $this->hasMany(OrderProduct::class);
    }

    public function computedSum($order)
    {
        return OrderProduct::select(new Expression('sum(price * count)'))
            ->where('order_id', $order->id);
    }
}

Now, we can get order sum with $order->sum. Yep, we can get this functionality with getSumAttribute but wait! The real power of this package is that we can use this method inside our queries:

$orders = Order::withComputed('sum')->get()

We eager loaded sum attribute without N+1 problem.

But there is more! You can add having or orderBy clauses to such queries for filtering and sorting!

Order::withComputed('sum')->orderBy('sum', 'desc')->get()

Installation

You can install the package via composer:

composer require n7olkachev/laravel-computed-properties

Next, add ComputedProperties trait to your models:

use ComputedProperties;

That's all!

More examples

class Page extends Model
{
    use ComputedProperties;

    public $timestamps = false;

    protected $casts = [
        'last_view' => 'datetime',
        'first_view' => 'datetime',
    ];

    public function computedLastView($page)
    {
        return PageView::select(new Expression('max(viewed_at)'))
            ->where('page_id', $page->id);
    }

    public function computedFirstView($page)
    {
        return PageView::select(new Expression('min(viewed_at)'))
            ->where('page_id', $page->id);
    }
}

We can find Page by its first view:

$page = Page::withComputed('first_view')
    ->having('first_view', Carbon::create(2017, 8, 16, 0, 0, 0))
    ->first();

Or by both first_view and last_view

$page = Page::withComputed(['first_view', 'last_view'])
    ->having('first_view', Carbon::create(2017, 8, 16, 0, 0, 0))
    ->having('last_view', Carbon::create(2017, 8, 21, 0, 0, 0))
    ->first();

We can order pages by theirs last_view

$pages = Page::withComputed('last_view')
    ->orderBy('last_view', 'desc')
    ->get()

Testing

$ composer test

Credits

Sponsored by

https://websecret.by/

Web agency based in Minsk, Belarus

License

The MIT License (MIT)

About

Make your accessors smarter

Resources

Stars

Watchers

Forks

Packages

No packages published

Languages

  • PHP 100.0%