Laravel Eloquent ORM 2-in-1 Methods
Tags: laravel, eloquent, orm
Published: 2022-11-28 11:31:10

## Overview

[Eloquent](https://laravel.com/docs/master/eloquent) is an object-relational mapper (ORM) that makes it enjoyable to interact with your database.

**ORM** allow us to have a neat structure within our codebase with concept of **Models**. A Model in this case will be a representation of a database row as well as entity relationship.

## Concepts
A Model has mainly 3 responsibilities:

1. Manage **persistence** of data and **relationship**
2. Hold data **in Memory**
3. Implement **business logic**

We will be focusing on some useful methods in Eloquent which encapsulate 2 responsibility in one. The benefit of this is it reduces codes and conditional statements in your logic.

## 2-in-1 Functions
### Retrieving Or Creating Record
- `firstOrCreate()` will attempt to retrieve a record using the given data. However in case the record was not found, new record will be created and persisted to the database using given data.
- `firstOrNew()` similar to `firstOrCreate()` however if no records were found a new instance of the model will be returned with the given data but data will not automatically be persisted. A manual intervention will be required by calling `save()` methods on the instance returned.

```php
use App\Models\Flight;
 
// Retrieve flight by name 
// or create it if it doesn't exist...
$flight = Flight::firstOrCreate([
    'name' => 'London to Paris'
]);
 
// Retrieve flight by name 
// or create it with the name, delayed, and arrival_time attributes...
$flight = Flight::firstOrCreate(
    ['name' => 'London to Paris'],
    ['delayed' => 1, 'arrival_time' => '11:30']
);
 
// Retrieve flight by name 
// or instantiate a new Flight instance...
$flight = Flight::firstOrNew([
    'name' => 'London to Paris'
]);
 
// Retrieve flight by name 
// or instantiate with the name, delayed, and arrival_time attributes...
$flight = Flight::firstOrNew(
    ['name' => 'Tokyo to Sydney'],
    ['delayed' => 1, 'arrival_time' => '11:30']
);
```
### Updating Or Creating Records
- `updateOrCreate()` will attempt to update a record using the given data. However in case the record was not found, new record will be created and persisted to the database using given data.

```php
use App\Models\Flight;

// Update flight where departure and destination with price and discounted 
// or create new record with departure, destination, price and discounted
$flight = Flight::updateOrCreate(
    ['departure' => 'Oakland', 'destination' => 'San Diego'],
    ['price' => 99, 'discounted' => 1]
);
```

### Updating Or Creating Records (Batch)
- `upsert()` Enable us to inserts multiple rows into a database table if they do not already exist, or updates them if they do in a single query.

```php
use App\Models\Flight;

// The method's first argument consists of the values to insert or update, 
// while the second argument lists the column(s) that 
// uniquely identify records within the associated table.

// While the third argument is an array of the columns 
// that should be updated if a matching record 
// already exists in the database.
Flight::upsert(
    [
        ['departure' => 'Oakland', 'destination' => 'San Diego', 'price' => 99],
        ['departure' => 'Chicago', 'destination' => 'New York', 'price' => 150]
    ],
    ['departure', 'destination'],
    ['price']
);
```