Laravel: how to insert data with foreign key

Stefan Bogdanescu

Founder & Senior Architect · 2026-06-29

Laravel Company

Laravel: How to Insert Data with Foreign Keys – A Complete Guide

As a senior developer, I frequently encounter situations where setting up database relationships—specifically foreign keys—seems straightforward in migrations but becomes confusing when implementing the logic in Eloquent models and controllers. Dealing with relational data is central to any robust application, and mastering how Laravel handles these connections is key.

You've set up a perfect scenario: linking users to their respective addresses. The confusion often arises not from the database structure itself, but from correctly translating that structural relationship into working Eloquent relationships.

This guide will walk you through exactly how to establish these links, define the necessary Eloquent relationships, and successfully insert related data using Laravel.


1. Reviewing the Database Foundation (Migrations)

Before diving into the code, let's look at your migration setup, which is excellent. You have correctly defined the relationship constraint in your user_address table:

users Table:
(Contains the primary key, id)

user_address Table:

Schema::create('user_address', function (Blueprint $table) {
    $table->id();
    $table->unsignedBigInteger('user_id'); // This is the Foreign Key
    $table->foreign('user_id')->references('id')->on('users')->onUpdate('cascade')->onDelete('cascade');
    // ... other address fields
});

The foreign('user_id')->references('id')->on('users') line correctly enforces relational integrity. The onUpdate('cascade') and onDelete('cascade') options ensure that if a user is deleted, all their associated addresses are automatically removed, which is a best practice for data consistency.

2. Defining Eloquent Relationships (The Key Step)

The magic of Eloquent lies in defining these relationships in your models. By telling Laravel how the tables connect, you unlock powerful methods like eager loading and easy data retrieval.

The User Model

Since one user can have many addresses, the User model needs a hasMany relationship pointing to the User_Address model.

// app/Models/User.php

class User extends Authenticatable
{
    use HasFactory, Notifiable;

    // ... existing properties

    /**
     * Defines the one-to-many relationship: A user has many addresses.
     */
    public function addresses()
    {
        return $this->hasMany(User_Address::class);
    }
}

The User_Address Model

Conversely, the User_Address model needs a belongsTo relationship to point back to its parent user.

// app/Models/User_Address.php

class User_Address extends Model
{
    use HasFactory;

    protected $fillable = [
        'mobile_no',
        'shipping_address',
        'barangay',
        'city',
        'province',
        'user_id', // Ensure user_id is included if you manage it directly
    ];

    /**
     * Defines the many-to-one relationship: An address belongs to one user.
     */
    public function user()
    {
        return $this->belongsTo(User::class);
    }
}

By establishing these relationships, you are now ready to manage the data seamlessly within your Laravel application. This approach of defining clear relationships is fundamental to building scalable applications on Laravel Company.

3. Inserting Data: Linking Parent and Child Records

Now that the relationship is defined, inserting data involves handling two steps: ensuring the parent exists, and then creating the child record while referencing the parent's ID. We typically handle this logic in a controller.

Here is an example of how you would insert a new address for an existing user:

// Example Controller Method (e.g., UserController.php)

use App\Models\User;
use App\Models\User_Address;
use Illuminate\Http\Request;

class UserController extends Controller
{
    public function storeAddress(Request $request, User $user)
    {
        // 1. Validate incoming data (essential for security and integrity)
        $validatedData = $request->validate([
            'mobile_no' => 'nullable|integer',
            'shipping_address' => 'required|string',
            'city' => 'required|string',
            'province' => 'required|string',
        ]);

        // 2. Insert the new address, linking it via the authenticated user's ID
        $user->addresses()->create([
            'mobile_no' => $request->mobile_no,
            'shipping_address' => $request->shipping_address,
            'city' => $request->city,
            'province' => $request->province,
        ]);

        // 3. Return a success response
        return response()->json(['message' => 'Address successfully added!', 'address' => $user->addresses()->first()]);
    }
}

Explanation of the Insertion Logic:

  1. Route Model Binding: Notice we use User $user in the method signature. This is a Laravel feature that automatically finds and injects the correct User model based on the route parameters (e.g., /users/{user}). This avoids manually querying the database for the user, making the code cleaner.
  2. Chaining Relationships: We access the relationship defined earlier ($user->addresses()).
  3. Creating the Record: We call the create() method on that relationship. Laravel automatically handles setting the correct foreign key (user_id) to the current user's ID before persisting the new record into the user_address table.

Conclusion

Inserting data with foreign keys in Laravel is fundamentally about establishing and utilizing Eloquent relationships correctly. By meticulously defining the hasMany and belongsTo relationships in your models, you delegate the complex job of linking primary and foreign keys to the framework. When performing insertions, always rely on these established relationships rather than manually manipulating IDs. This practice ensures data integrity, improves code readability, and makes your application robust and maintainable—a core principle when developing with Laravel Company. Happy coding!