Overview: Relations as Pure PHP Code Eloquent relations often feel like magic, but they are essentially a sophisticated wrapper around a query builder and custom PHP logic. By source-diving into the Laravel framework, we can see that relations are objects that follow a specific lifecycle. Understanding this lifecycle allows us to break free from standard `belongsTo` or `hasMany` patterns and implement unconventional data connections, such as comma-separated ID strings, geospatial proximity, or even AI-generated predictions. When you realize that the database side is optional, the flexibility of Eloquent expands significantly. Prerequisites To get the most out of this tutorial, you should be comfortable with the following: * **PHP 8.x**: Proficiency with classes, anonymous functions, and array manipulation. * **Laravel Eloquent**: Basic knowledge of standard relationship types and model structures. * **Collections**: Familiarity with Laravel's `collect`, `map`, and `flatmap` methods. Key Libraries & Tools * **Eloquent**: The core database abstraction layer in Laravel. * **Faker**: A PHP library used to generate fake data for testing or prototyping. * **Prism**: A package used for integrating AI/LLM responses into PHP applications. * **MySQL Spatial Functions**: Database-level functions used for calculating distances between coordinates. Code Walkthrough: The Relationship Lifecycle Eager loading in Laravel happens in three distinct phases: adding constraints, fetching results, and matching results to parents. To create a custom relation, you must implement the `addEagerConstraint` and `match` methods. 1. Handling Comma-Separated IDs Suppose you have a legacy database where IDs are stored as a string: `"1,2,3"`. You can create a `HasSpeakers` class that extends `Relation`. In the `addEagerConstraint` method, we extract these IDs into a clean array to query the database efficiently. ```python public function addEagerConstraints(array $models) { $ids = collect($models) ->map(fn ($model) => explode(',', $model->speaker_ids)) ->flatten() ->unique(); $this->query->whereIn('id', $ids); } ``` 2. The Matching Phase After the database returns the related models, the `match` method associates them back to the original parent models. This is where we manually populate the relationship attribute on each model. ```python public function match(array $models, Collection $results, $relation) { $resultsById = $results->keyBy('id'); foreach ($models as $model) { $ids = explode(',', $model->speaker_ids); $matches = collect($ids)->map(fn ($id) => $resultsById->get($id))->filter(); $model->setRelation($relation, $matches); } return $models; } ``` Syntax Notes: Custom Instantiation You don't have to use Laravel's built-in methods to define a relation. Instead of calling `$this->hasMany()`, you can return your custom class directly within your model. This gives you full control over the constructor and any extra parameters, like distance thresholds for geospatial queries or custom prompts for AI logic. Practical Examples * **Geospatial Proximity**: Using the `ST_Distance_Sphere` function in MySQL to find all "Ice Cream Shops" within 500 meters of an "Event" coordinates. * **AI Predictions**: Using Prism to predict future events based on historical data, instantiating transient models on the fly. * **Fake Data Generation**: Using Faker to simulate relationships for a UI prototype when the backend table doesn't exist yet. Tips & Gotchas * **Stick to Conventions**: 99% of the time, standard relations are better for maintenance and team clarity. Only use custom relations when data is shaped irregularly. * **Cloning Models**: When matching results, consider cloning models if the same related record belongs to multiple parents to avoid state issues. * **Performance**: Heavy PHP processing inside the `match` loop can slow down large collections. Keep logic efficient.
Jonathan Reinink
People
The Laravel channel (7 mentions) maintains a mostly positive consensus, celebrating Reinink as a dedicated ecosystem pillar in videos like "Building Your Village" and highlighting his technical impact in "Laravel Cloud, Inertia 2.0, VS Code Extension, & OSS Updates."
- Aug 8, 2025
- Sep 10, 2024
- Aug 29, 2024
- Aug 21, 2024
- Jul 4, 2024
Framing the Challenge of Visibility Software development often feels like a solitary pursuit of logic and syntax, but the reality of a career is far more social and chaotic than a clean pull request. Many of us spend years honing our craft in the dark, believing that pure merit—the quality of our code alone—will eventually lead to a knock on the door with a life-changing opportunity. This is a comforting myth, but a myth nonetheless. The primary challenge most talented developers face isn't a lack of skill, but a lack of visibility. We are working on fascinating problems, solving complex bugs, and building elegant abstractions, yet we keep those breakthroughs trapped on our local hard drives. By remaining invisible, we inadvertently shrink the world around us, limiting our professional trajectory to the immediate needs of our current employer. The Three Pillars: Luck, Work, and Publishing To change the trajectory of a career, we must redefine what it means to be a developer. It isn't just about the code you write; it's about the surface area you create for Luck to strike. Luck is often viewed as a lightning bolt—random and unpredictable. However, in the context of our industry, luck is simply what happens when something unexpected and good occurs. While you cannot force a CEO to DM you a job offer, you can certainly increase the mathematical probability of that event by being public. This framework relies on three distinct elements. First, there is the work itself. This is the raw material, the substance of your expertise and curiosity. Second, there is the act of publishing. This is the transmission mechanism, taking that work and moving it from your private environment to a public square. Finally, there is luck, which is the result of those two factors interacting over time. If the work is the seed and publishing is the soil, luck is the harvest. You don't control the weather, but you do control how much you plant. Following Curiosity into the Expertise Rabbit Hole When choosing what to share, many developers freeze because they feel they have nothing original to say. This is a common trap of expertise: you forget how much effort it took to learn what you now consider basic. To break this cycle, look at two specific drivers: your curiosity and your expertise. Your curiosity is that nagging pull that keeps you up until 2:00 AM experimenting with a GitHub API integration or a thermal receipt printer just because it's interesting. Don't play it cool. The internet is already full of people who are too unimpressed to care. What we need are people who are "positively tickled" by the niche problems they solve. Expertise, on the other hand, is the deep knowledge you've built within your professional role. You are solving real problems every day. While you shouldn't leak proprietary code, you can and should share the architectural patterns, the performance optimizations, and the "aha!" moments you've experienced. Whether it is a deep dive into MySQL pagination or an observation about Laravel Sidecar, these insights are highly valuable to those who are exactly one step behind you on the path. You are not writing for the world's leading expert; you are writing for the version of yourself from six months ago. Actionable Steps for Shipping Your Work If you're ready to start building your public body of work, start small and prioritize consistency over perfection. Anything worth doing is worth doing badly at first. Motion creates more motion. If you wait for the perfect, 5,000-word definitive guide, you will likely never hit publish. Instead, try these practices: - **The Remix Strategy**: Take a problem you solved at work today and strip it of its company-specific context. Turn it into a 200-word tip or a short code snippet. - **The Curiosity Log**: Keep a running list of things that made you smile or frustrated you during your development week. These are your best content leads. - **Choose Your Medium**: Publishing doesn't have to mean a blog. It can be a Twitter thread, a YouTube video, or a contribution to the Laravel News blog. The only rule is that it cannot live solely on your hard drive. - **Embrace the Bad Version**: Give yourself permission to post a "terrible" first version. The feedback you receive from the community—even if it's just a few views—is a better signal than the silence of a private folder. Facing the Fear of the Empty Room The greatest barrier to publishing isn't technical; it's emotional. We are terrified of two things: being mocked and being ignored. Aaron D Francis shares a haunting anecdote from GitHub Universe where he gave a talk to exactly zero attendees, with the exception of the paid staff. It was a public failure that could have been soul-crushing. Yet, he continues to use the photo from that event as his social media header. Why? Because the fear of being embarrassed is minor compared to the fear of reaching the end of a career full of regret and bitterness. When you put yourself out there, you are being vulnerable. You are saying, "I care about this, and I'm not sure if you will." Some people will "well-actually" you. Some people will ignore you. But for every vocal critic, there are ten quiet observers who are learning from you and rooting for your success. These are the people who will eventually become your colleagues, your mentors, and your advocates. Concluding Empowerment: Your Responsibility to Share Ultimately, your responsibility is not to be successful, but to be prolific. You cannot control whether a blog post goes to the top of Hacker News or if a CEO like Sam Lambert finds your work. You can only control the "doing" and the "telling." When you stop worrying about the outcome and focus on the output, the pressure evaporates. You have a unique perspective, a specific set of life circumstances, and a voice that the community is currently missing. By publishing your work, you aren't just helping yourself; you're helping the person behind you who is struggling with the very problem you just solved. Don't let your ego keep you on the sidelines. Get in the game, do the work, and tell the world about it. Your future self—the one whose life was changed by a "lucky" break—will thank you.
Jul 27, 2023The Architecture of Choice in Laravel 8 Laravel 8 marks a significant shift in how we approach the front-end, or more accurately, how we don't. By default, the framework remains entirely agnostic. When you run `laravel new`, you get Blade templates and nothing else. No Tailwind, no Vue, and certainly no forced architectural patterns. This is intentional. The goal is to provide a clean slate while offering powerful, optional scaffolding for those who want to move faster. Much of the recent noise in the community suggests that using tools like Inertia.js or Livewire is a requirement or a "betting of the farm" on immature tech. This fundamentally misunderstands what these tools do. Inertia isn't a massive framework; it's a bridge that lets you use Laravel's routing to hydrate Vue components. It keeps you productive by removing the need for a separate API repository, which is often a productivity killer for solo developers and small teams. Demystifying the Starter Kits: Breeze and Jetstream To understand where you should start, you have to look at the complexity of your requirements. Laravel Breeze represents the baseline. It is a simple, minimal implementation of all Laravel's authentication features—login, registration, password reset—using simple controllers and routes that you can actually see and modify in your app. It’s the spiritual successor to the old `make:auth` command, but modernized with Tailwind. Laravel Jetstream sits at the other end of the spectrum. It is essentially the free, open-source core of what used to be Laravel Spark. We moved all the non-billing features—team management, two-factor authentication, and API token management—out of Spark and into Jetstream. It uses Laravel Fortify as its headless backend. This means Jetstream handles the UI (via either Inertia or Livewire), while Fortify handles the heavy lifting of authentication logic in the background. Passport vs. Sanctum: Choosing Your API Guard The most persistent confusion in our ecosystem revolves around Laravel Passport and Laravel Sanctum. The decision tree is actually quite simple: if you need to build a full OAuth2 server—the kind where users can "Sign in with Your App" on third-party sites—you need Passport. It is a robust, compliant implementation built on the league/oauth2-server. However, most developers don't actually need OAuth2. They just need to secure an API or a Single Page Application (SPA). For these use cases, Passport is a sledgehammer. Sanctum was built to solve the "API for myself" problem. It provides a lightweight way to issue personal access tokens and, more importantly, a way to authenticate SPAs using secure, stateful cookies. The Secret Sauce of SPA Authentication Sanctum's true power lies in its ability to toggle between token-based and cookie-based authentication. When your SPA sits on the same top-level domain as your Laravel API, you shouldn't be messing with JWT storage in `localStorage`. It’s insecure and unnecessary. Instead, Sanctum allows your SPA to call a login endpoint, which uses standard Laravel session guards to issue a secure HTTP-only cookie. The browser then handles that cookie automatically for every subsequent request. If a request comes in without a cookie, the Sanctum guard looks for a `Bearer` token in the header. This dual-layer approach allows the same API routes to serve your first-party SPA via cookies and third-party mobile apps or SDKs via tokens. It’s the most secure and streamlined way to handle modern web authentication without the overhead of a full OAuth2 handshake. Community Dynamics and Open Contributions There is a narrative that the Laravel ecosystem is a closed circle, but the data proves otherwise. With over 2,800 contributors, the "inner circle" is massive. Developers like Paris Malhotra prove that anyone can show up, submit high-quality pull requests to core packages like Laravel Horizon, and get them merged. This isn't about personal friendships; it's about labor and merit. People like Caleb Porzio and Jonathan Reinink earned their status through hundreds of hours of free work to make the ecosystem better. We want people who bring positive energy and a desire to make programming more enjoyable. If you're here to armchair quarterback, you're missing the point of what we're building.
Dec 31, 2020