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() { // } }