Eager Loading with JSON Columns in Laravel
Simplify Complex Relationships With Json

Search for a command to run...
Simplify Complex Relationships With Json

No comments yet. Be the first to comment.
A few months ago, my product manager dropped something in the team channel. "We are adding an AI agent to the platform next quarter. It will handle follow-ups automatically." Just like that. One messa

f you’re diving into React, you’ve likely come across the useRef hook. But what exactly is useRef(), and how can it make your life easier? In this post we’ll cover what useRef is, walk through five

A bug that only happens for some users, that you can never reproduce, that isn't in your code. Welcome to the React + browser-translation crash — what causes it, why it's so sneaky, and the battle-tested one-file fix.

Upgrading a core production database is usually the stuff of dev nightmares. It often involves maintenance windows, scheduled downtime, and the looming fear of a botched migration. But what if you cou

We are moving into products that adapt, predict and react with real context. Designing only interfaces is not enough anymore. We are designing experiences that understand the user. Designers and digital agencies are now challenged to move beyond trad...

Engineering at JoBins
167 posts
Welcome to Engineering at JoBins — where we share the stories, insights, and lessons from building a world-class hiring platform. From system design and scalability to developer tools and team culture, our engineers write about the real challenges we solve every day. Whether you're a curious developer or a fellow builder, we hope our experiences inspire and inform your own engineering journey.
Managing relationships among different entities has been a common requirement in the context of modern web applications. Relationships are maintained to organize and structure data in databases, facilitating efficient querying and manipulation of related data.
With this blog, I want to share a possible way to achieve our requirement to query and fetch related data on call. I faced a situation where I had to add cities for jobs, whereas cities are directly linked to prefectures. Previously, prefecture data for jobs was maintained in a separate pivot table. Now, I had to manage cities related to those prefectures selected for each job. Here, I am trying to showcase a solution to the problem with custom eager loading for cities based on JSON data, which might be helpful for you in a similar situation.
Let's start by defining our requirements:
Job Table: Store information related to jobs
Prefecture Table (job_prefecture): Stores information for prefectures selected, including a job_id to connect with the jobs table and prefecture_id referencing to prefectures.
City Table: Store information related to city categorise with prefecture_id
The approach is to to maintain city Ids within job_prefectures table by introducing JSON column city_ids.
At first, we add city_ids JSON column on to the job_prefecture table:
Php
php artisan make:migration add_column_city_ids_on_table_job_prefecture
Add following codes in the migration files:
Php
public function up()
{
Schema::table('job_prefecture', function(Blueprint $table)){
$table->json('city_ids')->nullable();
});
}
public function down()
{
Schema::table('job_prefecture', function(Blueprint $table)){
$table->dropColumn('city_ids');
});
}
To move on , you need to define relationships in Eloquent models:
JobPrefecture.php
Php
namespace App\Models
use Illumionate\Database\Eloquent\Model;
class JobPrefecture extends Model
{
public const TABLE_NAME = 'job_prefecture'
protected $casts = [
'city_ids' => 'array'
];
// Custom relationship for cities
public function cities()
{
$cityIds = $this->city_ids ?? [];
return City::whereIn('id', $cityIds)->get();
}
}
Php
namespace App\Repositories;
use App\Models\JobPrefecture;
class JobRepository
{
public function getJobDetail($id)
{
return Job::with('prefectures:id,name,job_id')->find($id);
}
public function getAllJobs()
{
return Job::with('prefectures:id,name,job_id')->get();
}
}
Php
namespace App\Http\Controllers;
use App\Repositories\PrefectureRepository;
use Illuminate\Http\Request;
class JobController extends Controller
{
public function __construct(protected JobRepository $jobRepository){}
public function index(Request $request)
{
$jobs = $this->jobRepository->getAllJobs()
->map(function($job) {
$job->prefecture->map(fn($prefecture)=>$prefecture->city)
});
return response()->json($prefectures);
}
}
https://laracoding.com/how-to-search-in-a-json-column-using-laravel-eloquent/
https://laraveljsonapi.io/docs/3.0/resources/relationships.html
To wrap up, modern web applications essentially require efficient management and relationship querying. In Laravel, by using JSON columns, data storage and retrieval can be simplified, minimizing the need for complex pivot tables. This approach can be implemented to maintain data integrity, enhancing performance with minimal database queries.
This technique can be useful to maintain dynamic relationships, ensuring scalability and performant behavior of the application. Laravel's Eloquent ORM feature can be leveraged to streamline development, making it easier to handle complex relationships in a managed and efficient way.
In this blog, I've demonstrated how to manage city data linked to prefectures within job records using a custom eager loading technique. Adding a JSON column to store cities' data with the definition of custom relationships in Eloquent models allows for efficient querying and retrieval of relevant data.
I hope you found this blog helpful! Feel free to reach out if you have any questions—I’m always here to help. 😊