Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

✨ Feat: Add firstOrInsert method to Query Builder with tests #54598

Draft
wants to merge 1 commit into
base: 11.x
Choose a base branch
from

Conversation

mohammadrasoulasghari
Copy link

This Pull Request introduces a new firstOrInsert method to the Laravel Query Builder.
The Laravel Query Builder currently lacks a firstOrInsert method, unlike Eloquent which offers both updateOrCreate and firstOrCreate. While updateOrInsert is available in the Query Builder, a dedicated firstOrInsert method was missing.
This omission has caused confusion and questions in forums, making the Query Builder less intuitive for common "find or create" scenarios. Developers often need a simple way to retrieve an existing record or create a new one if it doesn't exist, without the overhead of Eloquent models.

Implementation

The firstOrInsert method is implemented in the Illuminate\Database\Query\Builder class.

It works as follows:

  1. Attempts to retrieve the first record matching the provided $attributes using where and first.
  2. If a record is found, it is returned.
  3. If no record is found, a new record is inserted using insert, combining the $attributes and $values.
  4. The newly inserted record is then retrieved using where and first and returned.

Usage Example

DB::table('users')->firstOrInsert(
    ['email' => '[email protected]'],
    ['name' => 'Example User', 'password' => 'password']
);

This code will attempt to find a user with the email ‘[email protected]’.

Testing

This PR includes comprehensive unit tests to ensure the functionality and reliability of the firstOrInsert method. Tests cover scenarios for:

Retrieving existing records.
Inserting new records.
Using callable values for dynamic insertion.These tests provide confidence in the correctness of the implementation and will help prevent regressions in future changes.

This commit introduces a new `firstOrInsert` method to the Laravel Query Builder.

This method efficiently retrieves the first record matching the given attributes,
or inserts a new record with the provided attributes and values if no record is found.

It includes comprehensive unit tests to ensure its functionality and reliability.

This enhancement provides a convenient way to perform "first or insert" operations
directly within the query builder, improving developer workflow and code conciseness.
@taylorotwell
Copy link
Member

It's a bit more atomic to follow createOrFirst logic so there isn't a race condition.

@taylorotwell taylorotwell marked this pull request as draft February 13, 2025 15:39
@mohammadrasoulasghari
Copy link
Author

It's a bit more atomic to follow createOrFirst logic so there isn't a race condition.

s there any built-in infrastructure in Query Builder for handling unique constraints, similar to Eloquent’s createOrFirst() method? Or do I need to implement this functionality myself for Query Builder? it’s already implemented in Eloquent but I couldn’t find a suitable equivalent in Query Builder?

@taylorotwell
@shaedrich

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants