quick get start

Unmatched dimensions
The latest version of this document is 10.x , maintenance may be abandoned for the old version. It is recommended to read the latest version!

Eloquent: getting started

brief introduction

Laravel's Eloquent ORM provides a beautiful and concise ActiveRecord implementation to interact with the database. Each database table has a corresponding "model" to interact with the table. You can query the data in the data table through the model, and insert new records in the data table.

Before you begin, make sure that you config/database.php Configure database connections in. For more information about database configuration, see file

Model definition

First, create an Eloquent model. Models are usually app\Models Directory, but you can composer.json Files place them anywhere they can be automatically loaded. All Eloquent models need to inherit Illuminate\Database\Eloquent\Model Class.

The easiest way to create a model is to use make:model Artisan Command

 php artisan make : model Flight

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

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

When generating models, you may need to generate various other types of classes, such as model factories, seeders, and controllers. In addition, these options can be combined to create multiple classes at one time:

 php artisan make : model Flight -- factory php artisan make : model Flight - f php artisan make : model Flight -- seed php artisan make : model Flight - s php artisan make : model Flight -- controller php artisan make : model Flight - c php artisan make : model Flight - mfsc

Eloquent model convention

Now, let's take a look Flight The example of the model, we will use it from flights Retrieve and store data information in database tables:

 < ? php namespace App\Models ; use Illuminate\Database\Eloquent\Model ;

 class  Flight  extends  Model
 {
     //
 }

Datasheet Name

Please note that we did not tell Eloquent our Flight Which data table is used by the model. Unless another name is explicitly specified, the plural form of the class "snake name" will be used as the table name. Therefore, in this case, Eloquent will assume that Flight The model stores flights Data in the data table, and AirTrafficController The model stores records in air_traffic_controllers Table.

You can define table Property to specify a custom data table:

 < ? php namespace App\Models ; use Illuminate\Database\Eloquent\Model ;

 class  Flight  extends  Model
 {
     /** *Table name associated with the model * * @var string */
     protected $table =  'my_flights' ;
 }

Primary key

Eloquent will also assume that each data table has a id The primary key column of. You can define a protected $primaryKey Property to override the convention.

 < ? php namespace App\Models ; use Illuminate\Database\Eloquent\Model ;

 class  Flight  extends  Model
 {
     /** *Primary key associated with table * * @var string */
     protected $primaryKey =  'flight_id' ;
 }

In addition, Eloquent assumes that the primary key is an increasing integer value, which means that by default, the primary key will be automatically converted to int Type. If you want to use non incremental or non numeric primary keys, you need to set public $incrementing Property set to false

 < ? php class  Flight  extends  Model
 {
     /** *Whether the primary key is incremented actively * * @var bool */
     public $incrementing =  false ;
 }

If your primary key is not an integer, you need to set the protected $keyType Property set to string

 < ? php class  Flight  extends  Model
 {
     /** *Automatically increment the Primary Key Type * * @var string */
     protected $keyType =  'string' ;
 }

time stamp

By default, Eloquent expects your data table to exist created_at and updated_at Two fields. If you do not want Eloquent to automatically manage these two columns, please $timestamps Property set to false

 < ? php namespace App\Models ; use Illuminate\Database\Eloquent\Model ;

 class  Flight  extends  Model
 {
     /** *Whether to actively maintain the timestamp * * @var bool */
     public $timestamps =  false ;
 }

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

 < ? php namespace App\Models ; use Illuminate\Database\Eloquent\Model ;

 class  Flight  extends  Model
 {
     /** *Storage format of model date * * @var string */
     protected $dateFormat =  'U' ;
 }

If you need to customize the field name for storing timestamp, you can set it in the model CREATED_AT and UPDATED_AT Constant value:

 < ? php class  Flight  extends  Model
 {
     const  CREATED_AT  =  'creation_date' ;
     const  UPDATED_AT  =  'last_update' ;
 }

Database connection

By default, the Eloquent model will use the default database connection configured by your application. If you want to specify a different connection for the model, set $connection Properties:

 < ? php namespace App\Models ; use Illuminate\Database\Eloquent\Model ;

 class  Flight  extends  Model
 {
     /** *Database connection name of the model * * @var string */
     protected $connection =  'connection-name' ;
 }

Default attribute value

If you want to define default values for some attributes of the model, you can define them on the model $attributes Properties:

 < ? php namespace App\Models ; use Illuminate\Database\Eloquent\Model ;

 class  Flight  extends  Model
 {
     /** *Default values for model properties * * @var array */
     protected $attributes =  [
         'delayed'  =>  false ,
     ] ;
 }

Model retrieval

Create models and Its associated database table Then you can query data from the database. Think of each Eloquent model as a powerful Query Builder , you can use it to query the associated data table more quickly. For example:

 < ? php $flights = App\Models\Flight : : all ( ) ;

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

Additional constraint

Eloquent's all Method returns all the results in the model. Since each Eloquent model acts as a Query Builder , so you can also add query criteria, and then use get Method to obtain query results:

 $flights = App\Models\Flight : : where ( 'active' ,  one )
                - > orderBy ( 'name' ,  'desc' )
                - > take ( ten )
                - > get ( ) ;

Tip: Since Eloquent model is also a query constructor, you should also read Query Builder All available methods. You can use these methods in Eloquent queries.

Reload model

You can use fresh and refresh Method to reload the model. fresh Method retrieves the model from the database again. Existing model instances are not affected:

 $flight = App\Models\Flight : : where ( 'number' ,  'FR 900' ) - > first ( ) ; $freshFlight = $flight - > fresh ( ) ;

refresh Method to reassign the existing model with new data in the database. In addition, the loaded relationships will be reloaded:

 $flight = App\Models\Flight : : where ( 'number' ,  'FR 900' ) - > first ( ) ; $flight - > number =  'FR 456' ; $flight - > refresh ( ) ; $flight - > number ;  // "FR 900"

aggregate

Eloquent's all and get Method can query multiple results and return one Illuminate\Database\Eloquent\Collection example. Collection Class provides A large number of auxiliary functions To process Eloquent results:

 $flights = $flights - > reject ( function  ( $flight )  {
     return $flight - > cancelled ;
 } ) ;

You can traverse a collection like an array:

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

Result blocking

If you need to process thousands of Eloquent results, use chunk Command. chunk Method will retrieve the "blocks" in the Eloquent model and provide them to the specified Closure handle. When working with large result sets, use the chunk Method can save memory:

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

The first parameter that is passed to the method is the amount of data that you want each "block" to receive. The closure is passed as the second parameter and is called every time the partition is retrieved from the database. It will execute the database query and pass the result of the retrieval partition to the closure method.

If you want to filter based on the column to be updated when iteration results chunk Method, you should use chunkById method. Use in this case chunk Methods can lead to unexpected and inconsistent results:

 Flight : : where ( 'departed' ,  true ) - > chunkById ( two hundred ,  function  ( $flights )  { $flights - > each - > update ( [ 'departed'  =>  false ] ) ;
 } ) ;

Use Cursor

cursor Method allows you to traverse the database using a cursor, which executes a query only once. When processing a large amount of data, cursor Method can greatly reduce memory usage:

 foreach  ( Flight : : where ( 'foo' ,  'bar' ) - > cursor ( )  as $flight )  {
     //
 }

cursor return Illuminate\Support\LazyCollection example. Lazy collections It allows you to use most of the collection methods in the Larravel collection, and only loads a single model into memory each time:

 $users = App\Models\User : : cursor ( ) - > filter ( function  ( $user )  {
     return $user - > id >  five hundred ;
 } ) ;

 foreach  ( $users as $user )  { echo $user - > id ;
 }

Advanced Subquery

Select Subquery

Eloquent provides advanced subquery support. You can use a single query statement to extract information from related tables. For example, suppose we have a destination destinations And a flight schedule to the destination flights flights The table contains a arrival_at Field indicating when the flight arrives at the destination.

Use the select and addSelect Method, we can query all destinations with a single statement destinations , and the name of the last flight to each destination:

 use App\Models\Destination ; use App\Models\Flight ;

 return Destination : : addSelect ( [ 'last_flight'  => Flight : : select ( 'name' )
     - > whereColumn ( 'destination_id' ,  'destinations.id' )
     - > orderBy ( 'arrived_at' ,  'desc' )
     - > limit ( one )
 ] ) - > get ( ) ;

Sort by subquery

In addition, the query builder's orderBy The function also supports subqueries. We can use this function to sort all destinations according to the time when the last flight arrived at the destination. Similarly, this can only execute a single query on the database:

 return Destination : : orderByDesc ( Flight : : select ( 'arrived_at' )
         - > whereColumn ( 'destination_id' ,  'destinations.id' )
         - > orderBy ( 'arrived_at' ,  'desc' )
         - > limit ( one )
 ) - > get ( ) ;

Retrieving a single model/collection

In addition to retrieving all records from the specified data table, you can use the find first or firstWhere Method to retrieve a single record. These methods return a single model instance instead of a model collection:

 //Find a model by primary key $flight = App\Models\Flight : : find ( one ) ;

 //Find the first model matching the query criteria $flight = App\Models\Flight : : where ( 'active' ,  one ) - > first ( ) ;

 //Find the fast implementation of the first model that meets the query criteria $flight = App\Models\Flight : : firstWhere ( 'active' ,  one ) ;

You can also use the primary key array as a parameter to call find Method, which returns a set of matching records:

 $flights = App\Models\Flight : : find ( [ one ,  two ,  three ] ) ;

Sometimes you may want to perform other actions when you find the first result but cannot find the value. firstOr The method will return the first result when finding the result. If there is no result, the given callback will be executed. The return value of the callback will be used as firstOr Return value of method:

 $model = App\Models\Flight : : where ( 'legs' ,  '>' ,  one hundred ) - > firstOr ( function  ( )  {
         // ...
 } ) ;

firstOr Method also accepts an array of database columns to query:

 $model = App\Models\Flight : : where ( 'legs' ,  '>' ,  one hundred )
             - > firstOr ( [ 'id' ,  'legs' ] ,  function  ( )  {
                 // ...
             } ) ;

Not found exception

Sometimes you want to throw an exception when the model is not found. This is useful in controllers and routing. findOrFail and firstOrFail Method will retrieve the first result of the query. If it is not found, it will throw Illuminate\Database\Eloquent\ModelNotFoundException Exception:

 $model = App\Models\Flight : : findOrFail ( one ) ; $model = App\Models\Flight : : where ( 'legs' ,  '>' ,  one hundred ) - > firstOrFail ( ) ;

If no exception is caught, it will automatically return four hundred and four Respond to the user. That is to say, when using these methods, it is not necessary to write another check to return four hundred and four Response:

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

Retrieve Collection

You can also use Query Builder Provided count sum and max Methods, and others Aggregate function To manipulate the collection. These methods only return the appropriate scalar value instead of a model instance:

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

Insert and update models

insert

To add a record to the database, first create a new model instance, set properties for the instance, and then call save method:

 < ? php namespace App\Http\Controllers ; use App\Http\Controllers\Controller ; use App\Models\Flight ; use Illuminate\Http\Request ;

 class  FlightController  extends  Controller
 {
     /** *Create a new instance * * @param  Request  $request * @return Response */
     public  function  store ( Request $request )
     {
         //Verify request $flight =  new  Flight ; $flight - > name = $request - > name ; $flight - > save ( ) ;
     }
 }

In this example, we set the HTTP request parameters name Assigned to App\Flight Of the model instance name Property. When called save Method, a new record will be inserted. created_at and updated_at The time stamp will be set automatically without manual assignment.

to update

save Method can also be used to update existing models in the database. To update the model, you need to retrieve it first, set the properties to be updated, and then call save method. Similarly, updated_at The timestamp will be updated automatically, so manual assignment is not required:

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

Batch update

You can also update multiple models that match query criteria. In this example, all active Equal to 1 and destination by San Diego 's flights will be marked as delayed:

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

update The method requires an array whose key is the field name and value is the corresponding data. The array represents the fields that should be updated.

Note: When batch updating through Eloquent, the updated model will not be triggered saving , saved , updating and updated Model events. This is because the model is never actually retrieved during a batch update.

Check attribute changes

Eloquent provides isDirty , isClean and wasChanged Method to check the internal state of the model and determine how its properties have changed since it was originally loaded.

isDirty Method to determine whether any properties have changed since the model was loaded. You can pass a specific attribute name to determine whether a specific attribute is dirty. isClean Methods and isDirty Instead, it also accepts optional attribute parameters:

 $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 - > isClean ( ) ;  // false $user - > isClean ( 'title' ) ;  // false $user - > isClean ( 'first_name' ) ;  // true $user - > save ( ) ; $user - > isDirty ( ) ;  // false $user - > isClean ( ) ;  // true

wasChanged Method to determine whether any properties were changed when the model was last saved in the current request cycle. You can also pass attribute names to see if specific attributes have changed:

 $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 ( 'first_name' ) ;  // false

getOriginal Method returns an array containing the original properties of the model, ignoring any changes made since the model was loaded. You can pass a specific attribute name to get the original value of a specific attribute:

 $user = User : : find ( one ) ; $user - > name ;  // John $user - > email ;  //  john@example.com $user - > name =  "Jack" ; $user - > name ;  // Jack $user - > getOriginal ( 'name' ) ;  // John $user - > getOriginal ( ) ;  //Original attribute array

Batch assignment

You can also use create Method to save the new model. This method returns the model instance. However, before using, you need to specify on the model fillable or guarded Attribute, because all Eloquent models cannot be assigned in batches by default.

When a user passes in an unexpected HTTP parameter through a request and the parameter changes a field in the database that you do not need to change, a bulk assignment vulnerability will occur. For example, malicious users may pass in through HTTP requests is_admin Parameter, and then pass it to create Method. This operation enables users to upgrade themselves to administrators.

Therefore, before starting, you should define which attributes on the model can be assigned in batches. You can use the $fillable Property. For example: Let Flight Model-based name Attributes can be assigned in batches:

 < ? php namespace App\Models ; use Illuminate\Database\Eloquent\Model ;

 class  Flight  extends  Model
 {
     /** *Batch assignable attribute * * @var array */
     protected $fillable =  [ 'name' ] ;
 }

Once we have set the attributes that can be assigned in batches, we can use the create Method inserts new data into the database. create Method will return the saved model instance:

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

If you already have a model instance, you can pass an array to fill Method to assign values:

 $flight - > fill ( [ 'name'  =>  'Flight 22' ] ) ;

Batch assignment&JSON column

When assigning the JSON column, you must $fillable The array specifies the assignable key of each column. For safety reasons guarded Property, Larravel does not support updating nested JSON properties:

 /** *Properties that can be assigned in batches. * * @var array */ $fillable =  [
     'options->enabled' ,
 ] ;

Batch assignment allowed

If you want all attributes to be assigned in batches, you can set $guarded Define as an empty array:

 /** *Attributes that cannot be assigned in batches * * @var array */
 protected $guarded =  [ ] ;

Other creation methods

firstOrCreate / firstOrNew

Here are two methods you may use to assign values in batches: firstOrCreate and firstOrNew firstOrCreate Method matches the data in the database with the given key/value pair. If the model cannot be found in the database, a record will be inserted containing the attributes of the first parameter and the optional attributes of the second parameter.

firstOrNew Method image firstOrCreate Method to try to find the record in the database through the given attribute. However, if firstOrNew If the method cannot find the corresponding model, it will return a new model instance. be careful firstOrNew The returned model instance has not been saved in the database, you need to call it manually save Method to save:

 //Retrieve flights by name. If it does not exist, create a new model and insert it into the database $flight = App\Models\Flight : : firstOrCreate ( [ 'name'  =>  'Flight 10' ] ) ;

 //Retrieve flights by name, or create a new model and insert it into the database using the name and delayed attributes and arraval_time attributes $flight = App\Models\Flight : : firstOrCreate (
     [ 'name'  =>  'Flight 10' ] ,
     [ 'delayed'  =>  one ,  'arrival_time'  =>  '11:30' ]
 ) ;

 //Retrieve the flight by name. If it does not exist, the returned model instance has not been saved to the database $flight = App\Models\Flight : : firstOrNew ( [ 'name'  =>  'Flight 10' ] ) ;

 //The model instance retrieved by name or returned by name and delayed properties and arrival_time properties has not been saved to the database $flight = App\Models\Flight : : firstOrNew (
     [ 'name'  =>  'Flight 10' ] ,
     [ 'delayed'  =>  one ,  'arrival_time'  =>  '11:30' ]
 ) ;

updateOrCreate

You may also encounter situations where you want to update an existing model or create a new model if it does not exist. Provided by Larravel updateOrCreate Method. be similar to firstOrCreate method, updateOrCreate Persistence model, so there is no need to call save()

 //If there is a flight from Auckland to San Diego, the price is set at 99 dollars
 //If the existing model is not matched, create a $flight = App\Models\Flight : : updateOrCreate (
     [ 'departure'  =>  'Oakland' ,  'destination'  =>  'San Diego' ] ,
     [ 'price'  =>  ninety-nine ,  'discounted'  =>  one ]
 ) ;

If you want to execute multiple upsert , you should use upsert method. The first parameter of this method is composed of the value to be inserted or updated, while the second parameter lists the column that uniquely identifies the record in the corresponding table. The third and last parameter of this method is a column array, that is, if there are matching records in the database, the column that should be updated. If timestamp is enabled on the model, upsert Method will be set automatically created_at and updated_at Timestamp:

 App\Models\Flight : : upsert ( [
     [ 'departure'  =>  'Oakland' ,  'destination'  =>  'San Diego' ,  'price'  =>  ninety-nine ] ,
     [ 'departure'  =>  'Chicago' ,  'destination'  =>  'New York' ,  'price'  =>  one hundred and fifty ]
 ] ,  [ 'departure' ,  'destination' ] ,  [ 'price' ] ) ;

Note: All databases except SQL Server require upsert The column in the second parameter of the method has a "primary" or "unique" index.

Delete Model

Can be called on the model instance delete Method to delete an instance:

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

Delete model through primary key

In the above example, when calling delete You need to find the corresponding model in the database first. In fact, if you know the primary key of the model, you can directly use destroy Method to delete the model without first searching the database. destroy In addition to accepting a single primary key as a parameter, the method also accepts multiple primary keys, or uses arrays aggregate To save multiple primary keys:

 App\Models\Flight : : destroy ( one ) ; App\Models\Flight : : destroy ( one ,  two ,  three ) ; App\Models\Flight : : destroy ( [ one ,  two ,  three ] ) ; App\Models\Flight : : destroy ( collect ( [ one ,  two ,  three ] ) ) ;

be careful: destroy Method to load each model separately and call delete Method to trigger deleting and deleted event.

Delete model through query

You can also run delete statements on the model. In this example, we will delete all flights marked as inactive. Like batch update, batch deletion does not start any model events for the deleted model:

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

Note: Pass Eloquent When executing a batch delete statement, it will not be triggered deleting and deleted Model events. Therefore, the model samples are never retrieved when the delete statement is executed.

Soft Delete

In addition to actually deleting database records, Eloquent You can also "soft delete" models. The soft deleted model is not really deleted from the database. In fact, it is set on the model deleted_at Property and write its value to the database. If deleted_at If the value is not empty, it means that the model has been soft deleted. If you want to enable the model soft deletion function, you need to use it on the model Illuminate\Database\Eloquent\SoftDeletes trait:

 < ? php namespace App\Models ; use Illuminate\Database\Eloquent\Model ; use Illuminate\Database\Eloquent\SoftDeletes ;

 class  Flight  extends  Model
 { use SoftDeletes ;
 }

skill: SoftDeletes Will automatically deleted_at Attribute converted to DateTime / Carbon example.

Of course, you need to deleted_at Fields are added to the data table. Laravel Of data migration There are ways to create this field:

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

 public  function  down ( )
 { Schema : : table ( 'flights' ,  function  ( Blueprint $table )  { $table - > dropSoftDeletes ( ) ;
     } ) ;
 }

Now, when you use the delete Method, the current date and time will be written deleted_at Field. At the same time, the queried results will automatically exclude records that have been soft deleted.

You can use trashed Method to verify whether the given model instance has been soft deleted:

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

Query Soft Delete Model

Include soft deleted models

As mentioned earlier, query results will automatically reject soft deleted results. Of course, you can use withTrashed Method to obtain models including soft deleted models:

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

withTrashed The method can also be used in relation Query:

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

Retrieve Soft Delete Models Only

onlyTrashed method only Get the soft deleted model:

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

Restore Soft Delete Model

Sometimes the soft deletion model is "canceled" and used on the soft deleted data restore The method can restore to the valid state:

 $flight - > restore ( ) ;

You can also use it in the query restore Method to quickly restore multiple models. Like other "batch" operations, this operation will not trigger any event of the model:

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

similar withTrashed method, restore The method is also used in relation Above:

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

Permanently delete

Sometimes you may need to actually delete a model from the database. To permanently delete a soft deleted model from the database, use the forceDelete method:

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

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

Copy Model

You can use replicate Method to copy a new instance that has not been saved to the database. This method is very useful when model instances share many of the same properties.

 $shipping = App\Models\Address : : create ( [
     'type'  =>  'shipping' ,
     'line_1'  =>  '123 Example Street' ,
     'city'  =>  'Victorville' ,
     'state'  =>  'CA' ,
     'postcode'  =>  '90001' ,
 ] ) ; $billing = $shipping - > replicate ( ) - > fill ( [
     'type'  =>  'billing'
 ] ) ; $billing - > save ( ) ;

Query Scope

global scope

The global scope can add constraints to all queries of the model. Laravel's Soft Delete The function is to use this feature to obtain "undeleted" models from the database. You can write your own global scope, which is simple and convenient to add constraints to each model query:

Write Global Scope

Writing a global scope is simple. Define an implementation Illuminate\Database\Eloquent\Scope Interface, and implement apply This method. According to your needs apply Add the queried where Conditions:

 < ? php namespace App\Scopes ; use Illuminate\Database\Eloquent\Builder ; use Illuminate\Database\Eloquent\Model ; use Illuminate\Database\Eloquent\Scope ;

 class  AgeScope  implements  Scope
 {
     /** *Add constraints to Eloquent query construction * * @param  \Illuminate\Database\Eloquent\Builder  $builder * @param  \Illuminate\Database\Eloquent\Model  $model * @return void */
     public  function  apply ( Builder $builder , Model $model )
     { $builder - > where ( 'age' ,  '>' ,  two hundred ) ;
     }
 }

Tip: If you need to add fields in the select statement, you should use addSelect Method instead of select method. This will effectively prevent unintentional replacement of existing select statements.

Apply Global Scope

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

 < ? php namespace App\Models ; use App\Scopes\AgeScope ; use Illuminate\Database\Eloquent\Model ;

 class  User  extends  Model
 {
     /** *The "booted" method of the model * * @return void */
     protected  static  function  booted ( )
     {
         static : : addGlobalScope ( new  AgeScope ) ;
     }
 }

After adding the scope User::all() The query of will generate the following SQL query statements:

 select *  from  `users` where `age`  >  two hundred

Anonymous Global Scope

Eloquent also allows the use of closures to define global scopes, so there is no need to write a separate class for a simple scope:

 < ? php namespace App\Models ; use Illuminate\Database\Eloquent\Builder ; use Illuminate\Database\Eloquent\Model ;

 class  User  extends  Model
 {
     /** *The "booted" method of the model * * @return void */
     protected  static  function  booted ( )
     {
         static : : addGlobalScope ( 'age' ,  function  ( Builder $builder )  { $builder - > where ( 'age' ,  '>' ,  two hundred ) ;
         } ) ;
     }
 }

Unscope Global

If you need to cancel the global scope for the current query, you need to use withoutGlobalScope method. This method only accepts the global scope class name as its unique parameter:

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

Or, if you use closures to define the global scope:

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

If you need to cancel some or all global scopes, you need to use withoutGlobalScopes method:

 //Cancel all global scopes User : : withoutGlobalScopes ( ) - > get ( ) ;

 //Cancel Partial Global Scope User : : withoutGlobalScopes ( [ FirstScope : : class , SecondScope : : class
 ] ) - > get ( ) ;

Local Scope

Local scope allows you to define a common set of constraints for reuse in your application. For example, you may often need to get all "popular" users. To define such a scope, you only need to add scope Prefix.

The scope always returns a query constructor instance:

 < ? php namespace App\Models ; use Illuminate\Database\Eloquent\Model ;

 class  User  extends  Model
 {
     /** *Query only the scope of popular users * * @param  \Illuminate\Database\Eloquent\Builder  $query * @return \Illuminate\Database\Eloquent\Builder */
     public  function  scopePopular ( $query )
     {
         return $query - > where ( 'votes' ,  '>' ,  one hundred ) ;
     }

     /** *Query only the active user's scope * * @param  \Illuminate\Database\Eloquent\Builder  $query * @return \Illuminate\Database\Eloquent\Builder */
     public  function  scopeActive ( $query )
     {
         return $query - > where ( 'active' ,  one ) ;
     }
 }

Use local scope

Once a scope is defined, the scope method can be called when querying the model. However, it is not necessary to include scope Prefix. You can even chain multiple scopes, such as:

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

With the help of or The query runtime integrates multiple Eloquent models and may need to use closure callbacks:

 $users = App\Models\User : : popular ( ) - > orWhere ( function  ( Builder $query )  { $query - > active ( ) ;
 } ) - > get ( ) ;

Because it may be a bit troublesome, Laravel provides "higher level" orWhere Method, which allows you to call the scope chain without using closures:

 $users = App\Models\User : : popular ( ) - > orWhere - > active ( ) - > get ( ) ;

dynamic scope

Sometimes you may want to define a scope that accepts parameters. This can be achieved by passing additional parameters to the scope. Scope parameters should be placed in $query After parameter:

 < ? php namespace App\Models ; use Illuminate\Database\Eloquent\Model ;

 class  User  extends  Model
 {
     /** *Restrict the scope of the query to include only users of the given type * * @param  \Illuminate\Database\Eloquent\Builder  $query * @param  mixed  $type * @return \Illuminate\Database\Eloquent\Builder */
     public  function  scopeOfType ( $query , $type )
     {
         return $query - > where ( 'type' , $type ) ;
     }
 }

In this way, parameters can be passed when calling the scope:

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

Model comparison

Sometimes it may be necessary to judge whether two models are "the same". is The method can be used to quickly verify whether two models have the same primary key, table, and database connection:

 if  ( $post - > is ( $anotherPost ) )  {
     //
 }

When using belongsTo hasOne morphTo and morphOne Relationship, is Methods are also available. This method is particularly useful when you want to compare a related model without issuing a query to retrieve the model:

 if  ( $post - > author ( ) - > is ( $user ) )  {
     //
 }

event

Eloquent model triggers several events, allowing you to hook to the following nodes in the model life cycle: retrieved creating created updating updated saving saved deleting deleted restoring restored replicating Events allow you to execute code whenever a particular model saves or updates the database. Each event receives a model instance through its constructor.

retrieved Event is triggered when an existing model looks up data from the database. When a new model is saved every time, creating and created The event is triggered. If the model already exists in the database and calls save method, updating / updated The event is triggered. In these cases, saving / saved The event is also triggered.

Note: When batch updating is performed through Eloquent saved and updated , deleting and deleted The event will not be triggered. This is because the model is not really acquired during batch update.

First, define a $dispatchesEvents Attribute to map several nodes of Eloquent model life cycle to your own Event class

 < ? php namespace App\Models ; use App\Events\UserDeleted ; use App\Events\UserSaved ; use Illuminate\Foundation\Auth\User as Authenticatable ;

 class  User  extends  Authenticatable
 { use Notifiable ;

     /** *Event mapping for models * * @var array */
     protected $dispatchesEvents =  [
         'saved'  => UserSaved : : class ,
         'deleted'  => UserDeleted : : class ,
     ] ;
 }

After defining and mapping the Eloquent event, you can use the event listeners These events have been handled.

Use Closures

Instead of using custom event classes, you can register closures that are executed when various model events are triggered. Usually, you should booted Register these closures in the method:

 < ? php namespace App\Models ; use Illuminate\Database\Eloquent\Model ;

 class  User  extends  Model
 {
     /** *The "booted" method of the model * * @return void */
     protected  static  function  booted ( )
     {
         static : : created ( function  ( $user )  {
             //
         } ) ;
     }
 }

If necessary, you can use the Queue Anonymous Event Listener This will instruct Larravel to use queue Execution model event listener:

 use function Illuminate\Events\queueable ;

 static : : created ( queueable ( function  ( $user )  {
     //
 } ) ) ;

Observer

Define Observer

If multiple events are monitored on a model, observers can be used to organize these listeners into a separate class. The method name of the observer class maps to the Eloquent event you want to listen to. These methods take the model as their only parameter. make:observer Artisan command can quickly create a new observer class:

 php artisan make : observer UserObserver -- model = User

This command will App/Observers Folder to place a new observer class. If this directory does not exist, Artisan will create it for you. Use the following methods to open the observer:

 < ? php namespace App\Observers ; use App\Models\User ;

 class  UserObserver
 {
     /** *Handle the User 'created' event * * @param  \App\Models\User  $user * @return void */
     public  function  created ( User $user )
     {
         //
     }

     /** *Handle the User 'updated' event * * @param  \App\Models\User  $user * @return void */
     public  function  updated ( User $user )
     {
         //
     }

     /** *Handle the User "deleted" event * * @param  \App\Models\User  $user * @return void */
     public  function  deleted ( User $user )
     {
         //
     }

     /** *Handle the User "forceDeleted" event * * @param  \App\Models\User  $user * @return void */
     public  function  forceDeleted ( User $user )
     {
         //
     }
 }

To register an observer, you need to call the observe method on the model to be observed. You can register observers in the boot method of the App Providers EventServiceProvider service provider of the application:

 use App\Models\User ; use App\Observers\UserObserver ;
 /** *Register any events for your application. * * @return void */
 public  function  boot ( )
 { User : : observe ( UserObserver : : class ) ;
 }

Disable Events

Occasionally, you may want to temporarily "disable" all events triggered by the model. You can use withoutEvents Method. withoutEvents Method accepts a closure as the only parameter. Any code executed in this closure will not trigger model events. For example, the following code will get and delete a App\Models\User Instance without triggering any model events. Any value returned by a given closure will pass withoutEvents Method returns:

 use App\Models\User ; $user = User : : withoutEvents ( function  ( )  use  ( )  { User : : findOrFail ( one ) - > delete ( ) ;

     return User : : find ( two ) ;
 } ) ;

Single model saving without events

Sometimes, you may want to "save" a given model without triggering any events. You can use saveQuietly Method to complete this operation:

 $user = User : : findOrFail ( one ) ; $user - > name =  'Victoria Faith' ; $user - > saveQuietly ( ) ;

This article was first published in LearnKu.com Website.

This translation is only for learning and communication purposes. Please note the translator, source and link of the article when reprinting
Our translation work follows CC protocol If our work infringes your rights and interests, please contact us in time.

Original address: https://learnku.com/docs/laravel/8.x/elo...

Translation address: https://learnku.com/docs/laravel/8.x/elo...

Previous Next
Introduction to L01 Basics
We will take you to develop a project from scratch and deploy it online. This course teaches professional and practical skills in Web development, such as Git workflow, Laravel Mix front-end workflow, etc.
L04 WeChat applet from zero to release
From the application for personal account of the small app, we will take you step by step to develop a WeChat applet until it is submitted to the WeChat console for online release.
Contributors: 10
Number of discussions: 4
Initiate a discussion Only the current version


zy5666
swoole
zero Likes| 6 replies| Code shorthand | Course version 8. x
Rxy-development
Laravel8. x supersert problem
zero Likes| 2 replies| Q&A | Course version 8. x
adsdawa
id ii
zero Likes| 0 replies| share | Course version 8.5