13

I have a model called Property which has an 'active' flag. I want a metric at the top of my resource which shows a count of active Properties.

My calculate method is exactly as in the doc but this shows all Properties rather than active ones:

public function calculate(Request $request)
{
    return $this->count($request, Property::class);
}

How can I add a filter?

I've tried a where clause:

public function calculate(Request $request)
{
    return $this->count($request, Property::class)->where('active','=',1);
}

And a query scope:

public function calculate(Request $request)
{
    return $this->count($request, Property::class)->active();
}

I thought I might be able to use the Nova filter I set up on the resource list page but that didn't seem to work either. I'm sure it's really easy but I haven't worked it out. Thanks for your help!

Drewster
  • 499
  • 5
  • 13
  • I don't know if there's a simple way. But You can look at this : https://github.com/beyondcode/nova-filterable-cards – Clément Baconnier Aug 27 '18 at 09:45
  • I had a look at that earlier. It's close to what I want but I always want it to be filtered rather than having a filter option. I can't really see how to just apply the filter always. – Drewster Aug 27 '18 at 10:34
  • I've been able to do a workaround for the total by summing the active but that won't work for trends and partitions. return $this->sum($request, Property::class, 'active'); – Drewster Aug 27 '18 at 10:56

1 Answers1

40

Your can use every type of Eloquent\Builder instance in the $model param.

Instead of:

public function calculate(Request $request)
{
    return $this->count($request, Property::class);
}

Set a Scope on your Model

App\Property.php
...
public function scopeActive($query)
{
    return $query->where('active', 1);
}
public function scopeInactive($query)
{
    return $query->where('active', 0);
}

And use this scope as the $model param in your calculate method, because the call of the scope returns a Eloquent\Builder Instance

public function calculate(Request $request)
{
    return $this->count($request, Property::active());
    // return $this->count($request, Property::inactive());
}

Edit Of course you can make the Eloquent Builder call inline:

public function calculate(Request $request)
{
    return $this->count($request, Property::where('active', 1));
}
Mario
  • 416
  • 5
  • 3
  • I must be doing something wrong. I already had my scopes set up for active and inactive exactly as you coded except that they're static. If I leave them static and use Property::active() I get 'Non-static method App\Property::active() should not be called statically but Property::where('active', 1) works perfectly! Thanks!! – Drewster Aug 27 '18 at 20:57
  • Did you prefix the active method name with scope (scopeActive)? Then it should be static callable from laravel, that are simple scopes that laravel does for a long time. I do it with scopes (cause i dont want the query logic in my nova file) and have no problems with it – Mario Aug 28 '18 at 07:20
  • Yes, the declaration is 'public static function scopeActive ($query) {' – Drewster Aug 28 '18 at 09:12
  • 1
    Try to remove static from the declaration, scopes in Laravel are defined with 'public function scropeSomething($query)', maybe laravel facades freaks out if you add static before (not tested, just a thought) – Mario Aug 28 '18 at 09:34