• Stars
    star
    193
  • Rank 195,113 (Top 4 %)
  • Language
    PHP
  • Created almost 7 years ago
  • Updated over 5 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Make your accessors smarter

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)