firstOrNew()
?
In Laravel, firstOrNew()
is a convenient method provided by Eloquent, the ORM (Object-Relational Mapping) used in Laravel. It allows you to retrieve the first record that matches the given conditions from the database. If no matching record is found, it creates a new instance of the model with the provided attributes, allowing you to work with it as if it already existed in the database.
Let's assume you are building a blog application using Laravel, and you have a Post
model that represents blog posts. Each post has a title
, content
, and a slug
to generate SEO-friendly URLs.
First, create the Post
model using the Artisan command:
php artisan make:model Post
Next, create a migration to define the table schema for the posts
table:
php artisan make:migration create_posts_table --create=posts
Edit the generated migration file (database/migrations/xxxx_xx_xx_create_posts_table.php
) and define the table columns:
public function up()
{
Schema::create('posts', function (Blueprint $table) {
$table->id();
$table->string('title');
$table->text('content');
$table->string('slug')->unique();
$table->timestamps();
});
}
Run the migration to create the posts
table:
php artisan migrate
Create a controller that will handle the logic to create or retrieve blog posts:
php artisan make:controller PostController
In the PostController
, let's add the method to handle the firstOrNew()
functionality:
use App\Models\Post;
use Illuminate\Http\Request;
public function findOrCreatePost(Request $request)
{
// Try to find a post with the provided slug
$post = Post::firstOrNew(['slog' => $request->input('slug')]);
// If the post was not found, set its attributes
if (!$post->exists) {
$post->title = $request->input('title');
$post->content = $request->input('content');
}
// Save the post to the database
$post->save();
// Return the post to the user
return response()->json($post);
}
This can also be simplified with a different syntax. Here we will pass in a second array to the firstOrNew()
function to be used if post was not found. Look at example below:
use App\Models\Post;
use Illuminate\Http\Request;
public function findOrCreatePost(Request $request)
{
// Try to find a post with the provided slug
$post = Post::firstOrNew(
['slog' => $request->input('slug')],
['title' => $request->input('title'), 'content' => $request->input('content')]
);
// Save the post to the database
$post->save();
// Return the post to the user
return response()->json($post);
}
In the routes/api.php
file, define a route to access the findOrCreatePost()
method in the PostController
:
use App\Http\Controllers\PostController;
Route::post('/posts', [PostController::class, 'findOrCreatePost']);
Now, you can test the findOrCreatePost()
method by sending a POST request to the /posts
endpoint with the title
, content
, and slug
data.
For example, using a tool like cURL:
curl -X POST <http://your-app-url/api/posts> -d "title=Sample Post&content=This is a sample blog post.&slug=sample-post"
If a post with the provided slug exists in the database, the endpoint will return the existing post. Otherwise, it will create a new post with the provided attributes and return the newly created post.
Conclusion
In this tutorial, you learned how to use firstOrNew()
in Laravel to find an existing record or create a new one if it doesn't exist. We applied this feature to a real-world example by building a blog post creation endpoint in a Laravel application. This functionality can be handy in many scenarios where you want to retrieve an existing record or create a new one based on some conditions.