Why don't you execute queries to do this, instead of filtering collections? I think it would be better in terms of performance and memory consumption.
Anyway, you can do what you want using custom collection:
// Stat model
public function newCollection(array $models = array())
{
return new StatsCollection($models);
}
// StatsCollection
use Illuminate\Database\Eloquent\Collection;
class StatsCollection extends Collection {
public function today()
{
return $this->filter(function ($item) {
return \Carbon\Carbon::today() == $item->created_at->startOfDay();
});
}
public function yesterday()
{
return $this->filter(function ($item) {
return \Carbon\Carbon::today()->subDay() == $item->created_at->startOfDay();
});
}
}
Hi,
Thanks for the reply. It looks very solid. Let me explain why I need collection filters.
In my controller's index method, I generate a shiny dashboard with loads of statistics/graphs. Making like 20 query using 20 lines of ->with() didn't sound right and maintainable to me. So instead, I wanted to pull all the data once, keep them in cache, and generate the view using filters.
Not sure which one is better. My solution feels less performant but more maintainable. What do you think?
Hi,
I agree with jarektkaczyk that filtering results might affect performance. To avoid having multiple with() statements on your dashboard controller method, you could use http://laravel.com/docs/responses#view-composers and fire an event to collect all necessary data from different sources (modules/packages) like so:
View::composer('acme::dashboard.main', function($view)
{
$notifications = Event::fire('display.notification.notification.events');
$view->with('user', Auth::user());
$view->with('notifications', array_filter($notifications));
});
beanmoss said:
Hi,
I agree with jarektkaczyk that filtering results might affect performance. To avoid having multiple with() statements on your dashboard controller method, you could use http://laravel.com/docs/responses#view-composers and fire an event to collect all necessary data from different sources (modules/packages) like so:
View::composer('acme::dashboard.main', function($view) { $notifications = Event::fire('display.notification.notification.events'); $view->with('user', Auth::user()); $view->with('notifications', array_filter($notifications)); });
This is not what I'm talking about. I use View composers in my app.
I need to do like 20x select query on the single table.(so either the composer or controller method with get 20x ->with()) So instead of X::all(), I'll do X::yesterday()->get(), X::today()->get(), X::where('a', 'b')->get(), X::count() etc.
That is why I wanted to do a single X::all() method in my controller, and filter the collection to my needs in the view layer.
Using all() is bad practice, but doing 20x ->with() also sounds bad practice. Not sure what should be the solution.
Perhabs I should render the page without any data, and request data with ajax after page loads?
Sign in to participate in this thread!
The Laravel portal for problem solving, knowledge sharing and community building.
The community