Eloquent & Database

Interview Questions: ORM, Performance, and Queues

Q1: What is the N+1 problem and how do you solve it?

Problem: Occurs when you loop through a collection of models and access a relationship that hasn't been loaded. Laravel executes one query to get the main models (N) and then one additional query for each model to get the relationship (+1).

Solution: Eager Loading using with().

// Bad: 101 queries for 100 posts
$posts = Post::all();
foreach($posts as $post) { echo $post->author->name; }

// Good: 2 queries
$posts = Post::with('author')->get();

Q2: Explain Polymorphic Relationships.

A polymorphic relationship allows a model to belong to more than one other model on a single association. For example, a Comment model might belong to both a Post and a Video.

Structure: The comments table needs commentable_id (integer) and commentable_type (string).

Q3: How do Queues work in Laravel and why use them?

Concept: Queues allow you to defer the processing of a time-consuming task (sending email, processing uploads) until a later time. This speeds up web requests.

Components:

  • Job: The class containing the logic (handle() method).
  • Queue Connection: Where jobs are stored (Redis, Database, SQS).
  • Worker: A background process (php artisan queue:work) that pulls jobs off the queue and executes them.

Q4: What are Accessors and Mutators?

Accessors: Format an attribute when retrieving it from the model. (e.g., `getFirstNameAttribute`).

Mutators: Format an attribute before saving it to the database. (e.g., `setFirstNameAttribute`).

New Syntax (Laravel 9+):

protected function firstName(): Attribute
{
    return Attribute::make(
        get: fn ($value) => ucfirst($value),
        set: fn ($value) => strtolower($value),
    );
}

Q5: Explain Soft Deletes.

Soft deleting a model doesn't actually remove the row from the database. Instead, it sets a deleted_at timestamp. Queries will automatically exclude these records unless you use withTrashed().

Implementation: Add the SoftDeletes trait to the model and a deleted_at column to the migration.

Q6: What are Scopes in Eloquent?

Scopes allow you to re-use common query logic.

  • Local Scopes: Defined on the model (e.g., `scopeActive`). Used as `User::active()->get()`.
  • Global Scopes: Applied automatically to all queries for a model (e.g., SoftDeletes is a global scope).

Q7: How do you handle Database Transactions in Laravel?

Transactions ensure that a set of database operations either all succeed or all fail (atomic). If an exception is thrown within the closure, the transaction is automatically rolled back.

DB::transaction(function () {
    DB::table('users')->update(['votes' => 1]);
    DB::table('posts')->delete();
});

Q8: What is the difference between `hasOne` and `belongsTo`?

It depends on where the foreign key is located.

  • belongsTo: The foreign key is on the current model's table. (e.g., A Post belongs to a User -> posts table has user_id).
  • hasOne: The foreign key is on the other model's table. (e.g., A User has one Profile -> profiles table has user_id).

Q9: How do you optimize Eloquent queries for large datasets?

  • Chunking: Process records in small groups to save memory. User::chunk(100, function ($users) { ... });
  • Cursors: Uses a generator to iterate through records one by one, keeping only one in memory. foreach (User::cursor() as $user) { ... }
  • Select specific columns: Don't select * if you don't need it. User::select('id', 'name')->get();