This whole article can be downloaded as a 28-page PDF. This is the most basic architecture you can possibly imagine.
The next step is to implement the publish and accept functionality: class ListingController extends Controller { public function publish(Listing $listing) { $listing->publish(); return response()->noContent(); } public function accept(Listing $listing) { $listing->accept(); return response()->noContent(); }}
The other option is to write the query in the Listing model: class Listing { public static function getOldListings(User $user) { return $user->listings() ->published() ->accepted() ->where('publish_at', ' subMonth()) ->get(); }}
Now the controller looks like this: class ListingController { public function __construct(private readonly ListingService $listingService) { } public function index() { return $this->listingService->getAll(); } public function show(Listing $listing) { if (!$listing->accepted || !$listing->published) { abort(404, 'Listing is not found'); } return $listing; } public function store(Request $request) { return $this->listingService->upsert($request->all()); } public function update(Request $request, Listing $listing) { return $this->listingService->upsert($request->all(), $listing); } public function destroy(Listing $listing) { $this->listingService->delete($listing); return response()->noContent(); } public function publish(Listing $listing) { try { $listing->publish(); } catch (CannotPublishListingException $ex) { abort(422, $ex->getMessage()); } return response()->noContent(); } public function accept(Listing $listing) { $this->listingService->accept($listing); return response()->noContent(); }}