roundly-consulting/comments-for-laravel
A drop-in comments system for Laravel. Add threaded, polymorphic comments to any Eloquent model with migrations, models, and a simple API, no third-party service required. Configurable and lightweight, it's ready to integrate into your app in minutes.
php artisan migrate.Post).return new CommentResource($post->comments()->create([...]));
config/comments.php, specifically comments.resources.author. That key controls the JSON shape of every comment's author and is the main extension point.GET /posts/{post}/comments endpoint returning a paginated CommentResource::collection(). The default payload is {id, ..., author: {id, type: "User"}} — enough for a frontend to render a comment list and link the author by ID.CommentResource::collection($comments) from index/show controllers. Paginate at the query level so the resource stays a thin serializer, and eager-load the author relation to avoid N+1s.PostResource:
'comments' => CommentResource::collection($this->whenLoaded('comments')),
Consistent use of whenLoaded keeps payloads predictable when comments aren't requested.App\Http\Resources\CommentAuthorResource extends JsonResource, add name, avatar_url, etc., and point comments.resources.author at it. The resource receives the author model, so $this->resource is your User (or other author model).id and type. Frontends and mobile clients should switch on type to choose a renderer, so treat it as an API constant rather than an implementation detail.type gives the client a discriminator (User, Page). Decide early whether that is your public contract or whether a custom resource should map to explicit strings.assertJsonPath('data.0.author.type', 'User') plus any custom fields. Add a test that swaps comments.resources.author to your custom class so config mistakes fail in CI, not production.type contract. author.type is now the author class basename (User), never the stored actor_type, full class name, or morph alias. Clients that parsed App\Models\User must be updated — this is a breaking change in payload values even though it fixes a class-name leak.author.type. If you configured a morph alias like user and relied on it appearing in JSON, it now renders User. Restore the old value deliberately via a custom author resource if clients depend on it.App\Models\User and Admin\Models\User both serialize as User. If you support multiple author namespaces, map them to distinct type strings in your custom resource.JsonResource subclass throws InvalidConfigurationException naming the key only when a comment is serialized. Run php artisan config:clear after editing, especially with cached config.JsonResource subclass; abstract classes, interfaces, or strings requiring constructor arguments won't work.$this->resource being null in custom resources instead of assuming a model.DB::listen or Telescope when adding fields.How can I help you explore Laravel packages today?