Laravel - Model
Eloquent Model
- https://laravel.com/docs/12.x/eloquent
- https://laravel.com/docs/12.x/queries
- https://laravel.com/docs/12.x/collections#available-methods
- https://laravel.com/docs/12.x/eloquent-relationships
Model creation
php artisan make:model ModelName -mfc
You can use optional flags to generate related files along with the model:
-m
or--migration
: Create a new migration file.-c
or--controller
: Create a new controller.-f
or--factory
: Create a new factory.-s
or--seed
: Create a new seeder.-r
or--resource
: Generate a resource controller.
The make:model
command will create:
app/Models/Post.php (the model)database/migrations/xxxx_xx_xx_create_posts_table.phpdatabase/factories/PostFactory.phpapp/Http/Controllers/PostController.php
Model Factory
App\Models\Job::factory()->create()
App\Models\User::factory(30)->create()App\Models\User::factory()->unverified()->create()
App\Models\Job::create(['title' => 'Acme Director', 'salary' => '1,000,000']);
Model API
- Model::
all
() - Model::
where
() - Model::
orderBy
() - Model::
get
() - Model::
first
() - Model::
firstWhere
() - Model::
firstOr
() - Model::
fresh
() - Model::
refresh
() - Model::
macro
() collect
()- Model::
reject
() - Model::
chunk
() - Model::
chunkById
() - Model::
each
() - Model::
update
() - Model::
lazy
() - Model::
lazyById
() - Model::
cursor
() - Model::
find
() - Model::
findOrFail
() - Model::
firstOrFail
() - Model::
firstOrCreate
() - Model::
firstOrNew
() - Model::
save
() - Model::
create
() - Model::
updateOrCreate
() - Model::
isDirty
() - Model::
isClean
() - Model::
wasChanged
() - Model::
getOriginal
() - Model::
fill
() - Model::
preventSilentlyDiscardingAttributes
() - Model::
upsert
()
Model Attributes
UUID
use HasUuids;$article->id; // "8f8e8478-9035-4d23-b9a7-62f4d2612ce5"
use HasUlids;$article->id; // "01gd4d3tgrrfqeda94gdbtdk5c"
Timestamps
// Not managed by Eloquentpublic $timestamps = false;// Default for Eloquent Modelscreated_atupdated_at//Specializedconst CREATED_AT = 'creation_date';const UPDATED_AT = 'updated_date';// The storage format of the model's date columnsprotected $dateFormat = 'U';// Perform model operations without the model having its// updated_at timestamp modifiedModel::withoutTimestamps(fn () => $post->increment('reads'));// The model's default values for attributes
Default Attributes
protected $attributes = [ 'options' => '[]', 'delayed' => false,];
Retrieving Eloquent Models
// all()foreach (Flight::all() as $flight) { echo $flight->name;}// Add additional constraints to queries and then invoke// the get method to retrieve the results$flights = Flight::where('active', 1) ->orderBy('name') ->take(10) ->get();// The fresh method will re-retrieve the model from the database// The existing model instance will not be affected$flight = Flight::where('number', 'FR 900')->first();$freshFlight = $flight->fresh();// The refresh method will re-hydrate the existing model using fresh// data from the database. In addition, all of its loaded relationships// will be refreshed as well:$flight = Flight::where('number', 'FR 900')->first();$flight->number = 'FR 456';$flight->refresh();$flight->number; // "FR 900"// Collections are "macroable", which allows you to add additional// methods to the Collection class at run timeCollection::macro('toUpper', function () { return $this->map(function (string $value) { return Str::upper($value); });});$collection = collect(['first', 'second']);$upper = $collection->toUpper();// the reject method may be used to remove models from a collection// based on the results of an invoked closure$flights = Flight::where('destination', 'Paris')->get();$flights = $flights->reject(function (Flight $flight) { return $flight->cancelled;});// The chunk method will retrieve a subset of Eloquent models,// passing them to a closure for processingFlight::chunk(200, function (Collection $flights) { foreach ($flights as $flight) { // ... }});// If you are filtering the results of the chunk method based// on a column that you will also be updating while iterating// over the results// The chunkById method will always retrieve models with// an id column greater than the last model in the previous chunkFlight::where('departed', true) ->chunkById(200, function (Collection $flights) { $flights->each->update(['departed' => false]); }, column: 'id');// The lazy method returns a flattened LazyCollection of Eloquent// models by chunk, which lets you interact with the results as// a single streamforeach (Flight::lazy() as $flight) { // ...}// If you are filtering the results of the lazy method based on a// column that you will also be updating while iterating over the resultsFlight::where('departed', true) ->lazyById(200, column: 'id') ->each->update(['departed' => false]);// The cursor method may be used to significantly reduce your application's// memory consumption when iterating through tens of thousands of// Eloquent model records// Execute a single database query; however, the individual Eloquent// models will not be hydrated until they are actually iterated over// Only one Eloquent model is kept in memory at any given time while// iterating over the curso// cursor() cannot eager load relationships, use lazy()foreach (Flight::where('destination', 'Zurich')->cursor() as $flight) { // ...}// Retrieve a model by its primary key...$flight = Flight::find(1);// Retrieve the first model matching the query constraints...$flight = Flight::where('active', 1)->first();// Alternative to retrieving the first model matching the query constraints...$flight = Flight::firstWhere('active', 1);// The findOr and firstOr methods will return a single model instance or,// if no results are found, execute the given closure.$flight = Flight::findOr(1, function () { // ...});$flight = Flight::where('legs', '>', 3)->firstOr(function () { // ...});// Sometimes you may wish to throw an exception if a model is not found// useful in routes or controllers$flight = Flight::findOrFail(1);$flight = Flight::where('legs', '>', 3)->firstOrFail();// If the ModelNotFoundException is not caught, a 404 HTTP response// is automatically sent back to the client:Route::get('/api/flights/{id}', function (string $id) { return Flight::findOrFail($id);});
Retrieving or Creating Models
// 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']);
Inserting and Updating Models
// To insert a new record into the database, you should instantiate// a new model instance and set attributes on the model.// Then, call the save method on the model instance:class FlightController extends Controller{ public function store(Request $request): RedirectResponse { // Validate the request... $flight = new Flight; $flight->name = $request->name; // The model's created_at and updated_at timestamps will // automatically be set when the save method is called $flight->save(); return redirect('/flights'); }}// Use the create method to "save" a new model using a single statement// Before using the create method, you will need to specify either a// fillable or guarded$flight = Flight::create([ 'name' => 'London to Paris',]);// save() method may also be used to update models that already exist$flight = Flight::find(1);$flight->name = 'Paris to London';$flight->save();// The updateOrCreate() method persists the model, so there's no// need to manually call the save() method// if a flight exists with a departure location of Oakland and a destination// location of San Diego, its price and discounted columns will be updated.// If no such flight exists, a new flight will be created which has the// attributes resulting from merging the first argument array with the// second argument array$flight = Flight::updateOrCreate( ['departure' => 'Oakland', 'destination' => 'San Diego'], ['price' => 99, 'discounted' => 1]);// All flights that are active and have a destination of San Diego// will be marked as delayed// The update() method returns the number of affected rows.Flight::where('active', 1) ->where('destination', 'San Diego') ->update(['delayed' => 1]);// The isDirty() method determines if any of the model's attributes// have been changed since the model was retrieved// The isClean() method will determine if an attribute has// remained unchanged since the model was retrieved$user = User::create([ 'first_name' => 'Taylor', 'last_name' => 'Otwell', 'title' => 'Developer',]);
$user->title = 'Painter';$user->isDirty(); // true$user->isDirty('title'); // true$user->isDirty('first_name'); // false$user->isDirty(['first_name', 'title']); // true
$user->isClean(); // false$user->isClean('title'); // false$user->isClean('first_name'); // true$user->isClean(['first_name', 'title']); // false
$user->save();
$user->isDirty(); // false$user->isClean(); // true// The wasChanged() method determines if any attributes were// changed when the model was last saved within the current// request cycle.$user = User::create([ 'first_name' => 'Taylor', 'last_name' => 'Otwell', 'title' => 'Developer',]);
$user->title = 'Painter';
$user->save();
$user->wasChanged(); // true$user->wasChanged('title'); // true$user->wasChanged(['title', 'slug']); // true$user->wasChanged('first_name'); // false$user->wasChanged(['first_name', 'title']); // true// The getOriginal() method returns an array containing the// original attributes of the model regardless of any changes// to the model since it was retrieved$user = User::find(1);$user->name; // John$user->email; // john@example.com$user->name = 'Jack';$user->name; // Jack
$user->getOriginal('name'); // John$user->getOriginal(); // Array of original attributes...// The getChanges() method returns an array containing the attributes// that changed when the model was last saved, while the getPrevious()// method returns an array containing the original attribute values// before the model was last saved$user = User::find(1);$user->name; // John$user->email; // john@example.com$user->update([ 'name' => 'Jack', 'email' => 'jack@example.com',]);$user->getChanges();/* [ 'name' => 'Jack', 'email' => 'jack@example.com', ]*/$user->getPrevious();/* [ 'name' => 'John', 'email' => 'john@example.com', ]*///
Mass Assignment
// The attributes that are mass assignable.protected $fillable = ['name'];// insert a new record in the database$flight = Flight::create(['name' => 'London to Paris']);// Already have a model instance, you may use the fill method to// populate it with an array of attributes$flight->fill(['name' => 'Amsterdam to Frankfurt']);// To make all of your attributes mass assignable, you may define// your model's $guarded property as an empty arrayprotected $guarded = []// Instruct Laravel to throw an exception when attempting to fill// an unfillable attributepublic function boot(): void{ Model::preventSilentlyDiscardingAttributes($this->app->isLocal());}// upsert() method may be used to update or create records in a single,// atomic operation. 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.// upsert() will automatically set the created_at and updated_at timestamps// if timestamps are enabled on the modelFlight::upsert([ ['departure' => 'Oakland', 'destination' => 'San Diego', 'price' => 99], ['departure' => 'Chicago', 'destination' => 'New York', 'price' => 150]], uniqueBy: ['departure', 'destination'], update: ['price']);
Deleting Models
// To delete a model$flight = Flight::find(1);$flight->delete();// If you know the primary key of the model, you may delete// the model without explicitly retrievingFlight::destroy(1);Flight::destroy(1, 2, 3);Flight::destroy([1, 2, 3]);Flight::destroy(collect([1, 2, 3]));// If you are utilizing soft deleting models, you may permanently// delete models via the forceDestroy methoFlight::forceDestroy(1);// Build an Eloquent query to delete all models matching your// query's criteria$deleted = Flight::where('active', 0)->delete();// To delete all models in a table, you should execute a query// without adding any conditions:$deleted = Flight::query()->delete();
Soft Deleting
// When models are soft deleted, they are not actually removed from// your database. Instead, a deleted_at attribute is set on the model// indicating the date and time at which the model was "deleted"class Flight extends Model{ use SoftDeletes;}// You should also add the 'deleted_at' column to your database table.// When querying a model that uses soft deletes, the soft deleted// models will automatically be excluded from all query resultsSchema::table('flights', function (Blueprint $table) { $table->softDeletes();});Schema::table('flights', function (Blueprint $table) { $table->dropSoftDeletes();});// To determine if a given model instance has been soft deleted,// you may use the trashed()if ($flight->trashed()) { // ...}// Restore soft delete$flight->restore();// Use the restore() method in a query to restore multiple modelsFlight::withTrashed() ->where('airline_id', 1) ->restore();// The restore method may also be used when building relationship queries$flight->history()->restore();// Use the forceDelete() method to permanently remove a soft deleted// model from the database table$flight->forceDelete();// Use the forceDelete method when building Eloquent relationship queries$flight->history()->forceDelete();// You may force soft deleted models to be included in a query's results// by calling the withTrashed method$flights = Flight::withTrashed() ->where('account_id', 1) ->get();// The withTrashed() method may also be called when building a// relationship query$flight->history()->withTrashed()->get();// The onlyTrashed() method will retrieve only soft deleted models$flights = Flight::onlyTrashed() ->where('airline_id', 1) ->get();
Pruning Models
Eloquent Model Relationships
- One To One
- One To Many
- Many To Many
- Has One Through
- Has Many Through
- One To One (Polymorphic)
- One To Many (Polymorphic)
- Many To Many (Polymorphic)