Create Custom Collections in Laravel
First of all we need to create a custom collection. I typically create a directory called Collections
in /app
.
<?php
namespace App\Collections;
use Illuminate\Database\Eloquent\Collection;
class PostsCollection extends Collection
{
public function toDropdown($key = 'id', $value = 'title')
{
return $this->keyBy($key)->map(function ($post) use ($value) {
return $post->getAttribute($value);
});
}
}
Now, we just need to tell the eloquent model that we want to use this collection instead of the default Illuminate\Database\Eloquent\Collection
.
<?php
namespace App;
use App\Collections\PostCollection;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Builder;
class Post extends Model
{
public function newCollection(array $models = [])
{
return new PostCollection($models);
}
}
Once we've added the hook above, we can use this collection in our controller like so.
<?php
namespace App\Http\Controllers;
use App\Post;
class RelatedPostsController extends Controller
{
public function index()
{
$postOptions = Post::query()
->published()
->publishedBeforeNow()
->orderByMostRecent()
->get()
->toDropdown('id', 'title');
return view('related-posts.create', compact('postOptions'));
}
}