Feature Request: Implement firstOrInsert for Query Builder - “Find or Create” Logic #54575
Unanswered
mohammadrasoulasghari
asked this question in
Ideas
Replies: 2 comments 4 replies
-
Hi. Nothing stops you from creating a macro for this. |
Beta Was this translation helpful? Give feedback.
0 replies
-
Yes, that's right, but considering its use and existence, doesn't it seem better to add Eloquent to the builder itself by default? |
Beta Was this translation helpful? Give feedback.
4 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
-
Hello Laravel team and community,
Currently, the Laravel Query Builder offers the updateOrInsert method, which is incredibly useful for ensuring records exist and updating them if necessary. However, there is no direct equivalent for a ‘find or create’ operation, like Eloquent’s firstOrCreate.
This functionality is particularly useful in scenarios where we need to ensure a record exists in the database, but don’t want to update it if it already does. A prime example is in migrations and seeders, where we often need to create default or initial data. In these contexts, using Eloquent models might be considered less ideal or unnecessary for simple record creation at the database level.
Proposed Solution:
If there is consensus on the usefulness of this feature, I would be happy to prepare a Pull Request with a proposed implementation of firstOrInsert for the Query Builder.
. This method would behave as follows:1. Attempt to find the first record matching the given where clauses.
2. If a record is found, return that record.
3. If no record is found, insert a new record with the provided values (along with the where clauses) and return the newly created record.
Use Cases:
Migrations: Ensuring default values or initial records exist for certain tables. For example, creating a default ‘admin’ user role if it doesn’t exist:
Schema::create('roles', function (Blueprint $table) { $table->id(); $table->string('name')->unique(); // ... other columns });
// Migration's up() method:
DB::table('roles')->firstOrInsert( ['name' => 'admin'], ['name' => 'admin', /* ... other default values */] // Values to insert if not found );
Current Workaround & Why firstOrInsert is Better:
Currently, to achieve ‘first or insert’ logic with the Query Builder, we need to perform two separate queries: first() to check existence, and insert() if needed. This approach is less efficient (two queries instead of potentially one in some database systems) and less readable.
A dedicated firstOrInsert method would streamline this common pattern, making the code cleaner and potentially more performant.
Consistency with updateOrInsert:
The Query Builder already provides updateOrInsert. Adding firstOrInsert would create a more consistent and complete API, offering both ‘find-or-modify’ and ‘find-or-create’ operations directly at the query level.
Call for Feedback:
I believe that adding firstOrInsert to the Query Builder would be a valuable addition, enhancing its usability and reducing boilerplate code in common scenarios. I would love to hear your thoughts on this proposal and whether it aligns with the direction of Laravel.
If there is consensus on the usefulness of this feature, I would be happy to prepare a Pull Request with a proposed implementation.
Thank you for your time and consideration.
Beta Was this translation helpful? Give feedback.
All reactions