Knowing when it's a Model or a Builder(Laravel)

intro image

User::where('id',1)->update([]) and User::find(1)->update([]) do the same thing but in different ways.


When working with databases in Laravel you usually find yourself either using Eloquent or the lower level Fluent queries.

Eloquent provides ways to “objectice” working with databases using the Fluent queries. Simply put its a wrapper around Fluent queries with extra cheese :).

Some underlying Mechanisms.

Generally, everything regarding Fluent queries can be found under the namespace Illuminate\Database\Query\Builder

And everything Eloquent under Illuminate\Database\Eloquent\Model

Further into Eloquent

If you know you know :)

Eloquent also has many parts to it, the main point of attraction the Model Class, Its own Query Builder Class as well other important classes like the Relations etc.

Examples Now let's try and break a couple of queries down

User::where('id',1) :This statement starts out as an eloquent model then once where is called the returned instance is that of the eloquent builder which means you can append more query methods. NB: The Eloquent Builder extends the Fluent Query Builder to perform its task. User::find(1) : This statement immediately returns a model instance of the record where the primary key is 1 NB: This will return an eloquent collection if multiple ids are passed to the find method eg find([1,2,3]

So the first query with the where method returns an instance of the query builder which means we can append more query builder methods as we go, and the fluent query when the called method does not exist within the eloquent builder class eg: the joinmethod.

With the second query, we can append both model and query builder methods still.

NB: Some methods exist in both the Builder and Model class.

So as you would imagine if you have a model instance the first point of reference of the method will be from the Model class and if not found will be looked up from the Query Builder. More or less like method overriding in the case of inheritance. But in this case, the magic method __call is used for this check https://github.com/laravel/framework/blob/5.7/src/Illuminate/Database/Eloquent/Model.php#L1602.

And one of such methods that exists in both the Builder and Model is the update method.

There are a few differences in the implementation of these updates with the one in the Model returning false if the model does not exist as well as allowing the user to pass in options such as whether to set the timestamp or not.

Why is it worth noting though?

Not that you might want to do this, but say for some reason you override the update method in a Model. Well, what this means is as long as you have a Model instance say like in our example above User::find(1)->update([...]) your overridden method will be executed.

But in the case, the other kind of query is used where a Builder is returned, your method will not run as the default update within the Builder will be called instead.

But hopefully, you don’t have to override any methods but find other cleaner ways to handle situations you might have.

What I am hoping to draw to light with this post though is the usefulness of understanding how things work and how it might come in handy one day :)

References Illuminate\Database\Eloquent | Laravel API Edit descriptionlaravel.com


https://github.com/laravel/framework/blob/5.7/src/Illuminate/Database/Eloquent/Model.php Eloquent: Getting Started - Laravel - The PHP Framework For Web Artisans Laravel - The PHP framework for web artisans.laravel.com