start


1. Introduction

The Eloquent ORM provided by Laravel provides a beautiful and simple ActiveRecord implementation that interacts with the database. Each data table corresponds to a "model" that interacts with the table. The model allows you to query data, insert, update, delete and other operations in the table.

Before you begin, make sure that you config/database.php The database connection is configured in the file. For more information about database configuration, see file

2. Define model

To begin, let's create an Eloquent model, which is usually located in app You can also place it in other directories composer.json The place where the file is automatically loaded. All Eloquent models inherit from Illuminate\Database\Eloquent\Model Class.

The easiest way to create model instances is to use Artisan commands make:model

 php artisan make:model User

If you want to generate Database migration , you can use --migration or -m Options:

 php artisan make:model User --migration php artisan make:model User -m

Eloquent model convention

Now, let's look at a Flight Model class example, we will use this class to obtain and access data tables flights Information in:

 <? php namespace App; use Illuminate\Database\Eloquent\Model; class Flight extends Model{ // }

Table name

Notice that we didn't tell Eloquent about our Flight Which table is used by the model. The default rule is that the plural of the model class name is used as its corresponding table name, unless other names are explicitly specified in the model class. So, in this example, Eloquent believes that Flight The model is stored and recorded in flights Table. You can also define in the model table Property to specify a custom table name:

 <? php namespace App; use Illuminate\Database\Eloquent\Model; class Flight extends Model{ /** *Data table associated to model * * @var string */ protected $table = 'my_flights'; }

Primary key

Eloquent's default primary key name for each table is id , you can define a $primaryKey Property to override the convention.

time stamp

By default, Eloquent expects created_at and updated_at It already exists in the data table. If you don't want these columns automatically managed by Larvel, set them in the model class $timestamps Property is false

 <? php namespace App; use Illuminate\Database\Eloquent\Model; class Flight extends Model{ /** *Indicates whether the model should be time stamped * * @var bool */ public $timestamps = false; }

If you need to customize the timestamp format, set the $dateFormat Property. This attribute determines how the date is stored in the database and the format of the date when the model is serialized as an array or JSON:

 <? php namespace App; use Illuminate\Database\Eloquent\Model; class Flight extends Model{ /** *Storage format of model date column * * @var string */ protected $dateFormat = 'U'; }

Database connection

By default, all Eloquent models use the default database connection in the application configuration. If you want to specify a different connection for the model, you can use the $connection Property to set:

 <? php namespace App; use Illuminate\Database\Eloquent\Model; class Flight extends Model{ /** * The connection name for the model. * * @var string */ protected $connection = 'connection-name'; }

3. Get multiple models

After creating the model and its associated data table, you need to prepare to obtain data from the database. Think of the Eloquent model as a powerful Query Builder , you can use it to smoothly query the data tables associated with it. For example:

 <? php namespace App\Http\Controllers; use App\Flight; use App\Http\Controllers\Controller; class FlightController extends Controller{ /** *Display all valid flight lists * * @return Response */ public function index() { $flights = Flight::all(); return view('flight.index', ['flights' => $flights]); } }

Access Column Values

If you have an Eloquent model instance, you can access the column values of the model by accessing its corresponding properties. For example, let's loop through each returned Flight Instance and output name Value of:

 foreach ($flights as $flight) { echo $flight->name; }

Add additional constraints

Eloquent's all Method returns all the results of the model table. Because every Eloquent model is a Query Builder , you can also add constraints to the query, and then use get Method to obtain the corresponding results:

 $flights = App\Flight::where('active', 1) ->orderBy('name', 'desc') ->take(10) ->get();
Note: Since the Eloquent model is essentially a query builder, you can use all the methods of the query builder in Eloquent queries.

aggregate

The method to obtain multiple results in Eloquent (such as all and get )The return value is Illuminate\Database\Eloquent\Collection An instance of, Collection Class provides several useful functions to process Eloquent results. Of course, you can simply cycle through this collection like you can operate on an array:

 foreach ($flights as $flight) { echo $flight->name; }

Chunking result set

If you need to process thousands of Eloquent results, you can use chunk Command. chunk Method will get a "chunk" Eloquent model and fill it into the given closure for processing. use chunk The method can effectively reduce memory consumption when processing a large number of data sets:

 Flight::chunk(200, function ($flights) { foreach ($flights as $flight) { // } });

The first parameter passed to this method is the number of "chunks" you want to obtain. Closures are called as the second parameter to process each chunk data obtained from the database.

4. Get single model/aggregation

Of course, in addition to obtaining all records from the given table, you can also use find and first Get a single record. These methods return a single model instance instead of a model collection:

 //Get model through primary key $flight = App\Flight::find(1); //Get the first model matching the query criteria $flight = App\Flight::where('active', 1)->first();

Not Found exception

Sometimes you may want to throw an exception when the model cannot be found, which is very useful in routing or controllers, findOrFail and firstOrFail Method will get the first result queried. However, if there are no query results, Illuminate\Database\Eloquent\ModelNotFoundException The exception will be thrown:

 $model = App\Flight::findOrFail(1); $model = App\Flight::where('legs', '>', 100)->firstOrFail();

If the exception is not captured, the HTTP 404 response will be sent to the user, so it is unnecessary to write an explicit check for the returned 404 response when using these methods:

 Route::get('/api/flights/{id}', function ($id) { return App\Flight::findOrFail($id); });

Get Aggregation

Of course, you can also use the query builder aggregation method, such as count sum max , and other query builders Aggregation method These methods return the calculated results rather than the whole model instance:

 $count = App\Flight::where('active', 1)->count(); $max = App\Flight::where('active', 1)->max('price');

5. Insert/Update Model

Basic Insert

To insert a new record in the database, just create a new model instance, set the properties of the model, and call save method:

 <? php namespace App\Http\Controllers; use App\Flight; use Illuminate\Http\Request; use App\Http\Controllers\Controller; class FlightController extends Controller{ /** *Create a new flight instance * * @param  Request  $request * @return Response */ public function store(Request $request) { // Validate the request... $flight = new Flight; $flight->name = $request->name; $flight->save(); } }

In this example, we simply allocate name Parameter value App\Flight The properties of the model instance, when we call save Method, a record will be inserted into the database. created_at and updated_at Timestamp on save Methods are automatically set when they are called, so there is no need to set them manually.

Basic update

save Method can also be used to update existing models in the database. To update a model, you should first obtain it, set the properties you want to update, and then call save method. Similarly, updated_at The timestamp will be updated automatically, so it is unnecessary to set its value manually:

 $flight = App\Flight::find(1); $flight->name = 'New Flight Name'; $flight->save();

The update operation can also modify multiple model instances provided by a given query at the same time. In this case, all valid and destination=San Diego 's flights are marked as delayed:

 App\Flight::where('active', 1) ->where('destination', 'San Diego') ->update(['delayed' => 1]);

update The method requires that key value pair parameters be passed in an array, representing the columns in the data table that should be updated.

Batch assignment

You can also use create Method to save a new model. This method returns the inserted model instance. But before that, you need to specify the fillable or guarded Property, because all Eloquent models are protected by Mass Assignment.

When a user passes an unexpected parameter value through an HTTP request, a security risk will arise, and then the parameter will modify the column value in the database in an unexpected way. For example, a malicious user sends a is_admin Parameter, which is then mapped to the create Method to allow users to turn themselves into administrators.

Therefore, you should define which attributes can be assigned in the model $fillable Property. For example, we set Flight On model name Attributes can be assigned:

 <? php namespace App; use Illuminate\Database\Eloquent\Model; class Flight extends Model{ /** *Attributes that can be assigned in batch * * @var array */ protected $fillable = ['name']; }

After setting the attributes that can be assigned, we can use create Method to insert a new record in the database. create Method returns the saved model instance:

 $flight = App\Flight::create(['name' => 'Flight 10']);

$fillable It is like a "white list" that can be assigned attributes. You can also choose to use $guarded $guarded Property contains an array of properties that you do not want to be assigned. Therefore, the attributes not included in it can be assigned. Therefore, the $guarded method is like a "blacklist". Of course, you can only use one of them at the same time - not together:

 <? php namespace App; use Illuminate\Database\Eloquent\Model; class Flight extends Model{ /** *Attributes that cannot be assigned in batch * * @var array */ protected $guarded = ['price']; }

In this example, except $price All attributes other than can be assigned.

Other creation methods

There are two other ways to create models: firstOrCreate and firstOrNew firstOrCreate Method first attempts to find a record in the database through the given column/value pair. If it is not found, a new record will be created through the given attribute.

firstOrNew Methods and firstOrCreate The same method is used to first try to find a matching record in the database. If it is not found, a model instance will be returned. Pay attention to passing firstOrNew The model instance returned by the method is not persisted to the database. You need to call save Method manual persistence:

 //Get the flight through the attribute. If it does not exist, create it $flight = App\Flight::firstOrCreate(['name' => 'Flight 10']); //Get the flight through the attribute. If it does not exist, initialize a new instance $flight = App\Flight::firstOrNew(['name' => 'Flight 10']);

6. Delete Model

To delete a model, call the delete method:

 $flight = App\Flight::find(1); $flight->delete();

Delete model through primary key

In the above example, we call delete The method obtains the model from the database before. However, if you know the primary key of the model, you can call the destroy method to delete it directly without obtaining it:

 App\Flight::destroy(1); App\Flight::destroy([1, 2, 3]); App\Flight::destroy(1, 2, 3);

Delete model through query

Of course, you can also delete multiple models by querying. In this example, we delete all flights marked as invalid:

 $deletedRows = App\Flight::where('active', 0)->delete();

Soft Delete

In addition to deleting records from the database, Eloquent can also "soft delete" models. When models are soft deleted, they are not really deleted from the database, but set a deleted_at Property and insert it into the database. If the model has a non empty deleted_at Value, the model has been soft deleted. To enable soft deletion of a model, you can use the Illuminate\Database\Eloquent\SoftDeletes Trait and add deleted_at Column to $dates Properties:

 <? php namespace App; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\SoftDeletes; class Flight extends Model{ use SoftDeletes; /** *The attribute should be adjusted to date * * @var array */ protected $dates = ['deleted_at']; }

Of course, you should add deleted_at Column to the data table. The Larravel Schema builder contains a help function to create this column:

 Schema::table('flights', function ($table) { $table->softDeletes(); });

Now, when you call the delete Method, deleted_at The column will be set as the current date and time, and when a soft deleted model is queried, the soft deleted model will be automatically excluded from the query results.

To determine whether a given model instance has been soft deleted, you can use trashed method:

 if ($flight->trashed()) { // }

Query Soft Deleted Models

Include soft deleted models

As mentioned above, the soft deletion model will be automatically excluded from the query results. However, if you want the soft deletion model to appear in the query results, you can use withTrashed method:

 $flights = App\Flight::withTrashed() ->where('account_id', 1) ->get();

withTrashed Methods can also be used in association queries:

 $flight->history()->withTrashed()->get();

Get Soft Delete Models Only

onlyTrashed Method of obtaining soft deletion model:

 $flights = App\Flight::onlyTrashed() ->where('airline_id', 1) ->get();

Restore Soft Delete Model

Sometimes you want to restore a soft deleted model, you can use restore method:

 $flight->restore();

You can also use it in the query restore Method to quickly restore multiple models:

 App\Flight::withTrashed() ->where('airline_id', 1) ->restore();

and withTrashed In the same way, restore Methods can also be used for association queries:

 $flight->history()->restore();

Permanently delete model

Sometimes you really need to delete a model from the database. You can use forceDelete method:

 //Force deletion of a single model instance $flight->forceDelete(); //Force deletion of all associated models $flight->history()->forceDelete();

7. Query Scope

global scope

Global scope allows us to add conditional constraints for all queries of a given model. Larave's built-in soft delete function uses the global scope to pull all the models that have not been deleted from the database. Writing a custom global scope can provide a convenient and simple way to ensure that each query of a given model has specific constraints.

Write Global Scope

Customizing the global scope is simple. First, define an implementation Illuminate\Database\Eloquent\Scope Interface class, which requires you to implement a method: apply. If necessary, you can visit apply Method where Condition to query:

 <? php namespace App\Scopes; use Illuminate\Database\Eloquent\Scope; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Builder; class AgeScope implements Scope{ /** * Apply the scope to a given Eloquent query builder. * * @param  \Illuminate\Database\Eloquent\Builder  $builder * @param  \Illuminate\Database\Eloquent\Model  $model * @return void */ public function apply(Builder $builder, Model $model) { return $builder->where('age', '>', 200);     } }

Apply Global Scope

To assign a global scope to a model, you need to override the boot Method and use addGlobalScope method:

 <? php namespace App; use App\Scopes\AgeScope; use Illuminate\Database\Eloquent\Model; class User extends Model{ /** * The "booting" method of the model. * * @return void */ protected static function boot() { parent::boot(); static::addGlobalScope(new AgeScope);     } }

After adding a scope, if you use User::all() The query will generate the following SQL statements:

 select * from `users` where `age` > 200

Anonymous global scope

Eloquent also allows us to use closures to define global scopes, which is particularly useful when implementing simple scopes. In this way, we don't need to define a separate class:

 <? php namespace App; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Builder; class User extends Model{ /** * The "booting" method of the model. * * @return void */ protected static function boot() { parent::boot(); static::addGlobalScope('age', function(Builder $builder) { $builder->where('age', '>', 200); });     } }

We can also remove global effects in the following ways:

 User::withoutGlobalScope('age')->get();

Remove Global Scope

If you want to remove the specified global scope from a given query, you can use the withoutGlobalScope

 User::withoutGlobalScope(AgeScope::class)->get();

If you want to remove some or all global scopes, you can use withoutGlobalScopes method:

 User::withoutGlobalScopes()->get(); User::withoutGlobalScopes([FirstScope::class, SecondScope::class])->get();

Local Scope

Local scope allows us to define a common set of constraints for reuse in applications. For example, you may often need to obtain the most popular users. To define such a scope, simply add a scope Prefix. The scope always returns the query builder:

 <? php namespace App; use Illuminate\Database\Eloquent\Model; class User extends Model{ /** *Query scope containing only active users * * @return \Illuminate\Database\Eloquent\Builder */ public function scopePopular($query) { return $query->where('votes', '>', 100); } /** *Only include the query scope of the active user * * @return \Illuminate\Database\Eloquent\Builder */ public function scopeActive($query) { return $query->where('active', 1); } }

Use Query Scope

After the scope is defined, you can call the scope method when querying the model, but you do not need to add scope Prefix, you can even call multiple scopes at the same time, for example:

 $users = App\User::popular()->active()->orderBy('created_at')->get();

dynamic scope

Sometimes you may want to define a scope that can receive parameters. You just need to add additional parameters to your scope. Scope parameters should be defined in $query After parameter:

 <? php namespace App; use Illuminate\Database\Eloquent\Model; class User extends Model{ /** *Only query scope for users of type * * @return \Illuminate\Database\Eloquent\Builder */ public function scopeOfType($query, $type) { return $query->where('type', $type); } }

Now, you can pass parameters when calling the scope:

 $users = App\User::ofType('admin')->get();

8. Events

Eloquent model can trigger events, allowing you to call the following methods at multiple time points in the model life cycle: creating created updating updated saving saved , deleting deleted restoring restored Events allow you to execute code every time a specified model class is saved or updated.

Basic use

When a new model is saved for the first time, creating and created The event will be triggered. If a model already exists in the database and calls save method, updating/updated The event will be triggered. The saving/saved event will be called whether it is created or updated.

For example, we have Service Provider An Eloquent event listener is defined in. In the event listener, we will call the isValid Method. If the model is invalid, it will return false If it returns from the Eloquent event listener false Then cancel save/update Operation:

 <? php namespace App\Providers; use App\User; use Illuminate\Support\ServiceProvider; class AppServiceProvider extends ServiceProvider{ /** *Start all application services * * @return void */ public function boot() { User::creating(function ($user) { if ( ! $user->isValid()) { return false; } }); } /** *Registered Service Provider * * @return void */ public function register() { // } }

give the thumbs-up Cancel Like Collection Cancel Collection

<<Previous: Fill Data

>>Next: Association