There is a lot going on with Laravel's Eloquent ORM, but to start things off in this series, we will actually start things off and look at how Eloquent Models boot up and construct themselves.

For this tutorial, we will use this model as our example.

class Post extends Eloquent
{
    $fillable = ['title', 'content'];
}

This is so that we are looking at just the default behavior of Eloquent before we start hacking things.

Now we will look at what happens when you call new Post(['post.title' => 'First Post', 'content' => 'lorem']).

First we dive into __construct: The First thing that happens is that we check to see if this Model checks if it has been booted. It does this by checking the booted static property on the parent Eloquent class with an array key of Post in this case. Since this the first time we are constructing an instance of our Post model, we need to boot it.

Now in boot we will have to do some mild trickery: Essentially, boot goes through the Post model and finds all of the mutators using a RegEx and stores it into the mutatorCache on Eloquent in a Post keyed array. Then we go ahead and set booted['Post'] to true so we will not have to perform this again the next time we need an instance of Post.

Finally, in a regular constructor, we only call fill with the attributes passed in to the constructor. In fill we will go through each of our attributes and do the following. First, we check if the attribute has a dot syntax for the key. This is used to remove any table names that may have been included such as post.title and then changes it to title. Now we check if the attribute is allowed within mass assignment by calling isFillable.

In isFillable, we ceheck a few different ways that mass assignment could be handled. First we want to see if the model is set to be unguarded: if so, we allow assignment. Next we check if the attribute is in the fillable array, then we once again allow assignment. Then we check if it isGuarded where we check if the key is in the guarded array or if guarded contains a splat array('*') (which is the default): if so, then we do not allow mass assignment. Finally if fillable is empty we return true unless the key starts with an underscore which is a convention list hidden attributes common in Rails.

If we found the key to be unfillable, we check to see if the model is totallyGuarded. Essentially, this means that if fillable is empty and guarded is a splat, then we will throw a MassAssignmentException. This means that if you do not modify the fillable or guarded properties, MassAssignmentExceptions will be thrown when you try to call fill.

But if we allow the attribute to be filled, then we need to setAttribute. Here we check for mutators in the mutatorCache from before. If there is a match, then we call this custom mutator which can contain any logic that we want. Next we check if the key is in the dates array. If so, we set the value to an instance of Carbon which is a powerful extention of PHP's Date object. At the end of this, we set the key within the attributes array to the value.

Finally, we return this instance to the user and our Eloquent Model is entirely booted up. Note, that the constructor deals in no way with relationships, the database, or modification of data.