Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Fields in Laravel Eloquent models

I am new to Laravel and Eloquent, so excuse me if this is a totally stupid question. I have been looking at how to create a model at both the documentation here and also another tutorial here (in the Creating Models using Eloquent ORM section) and I've noticed that the actual fields of the table are never mentioned, unless there is something specific about them (like having a relationship with another table, or not requiring mass assignment, or if they need to be hidden from JSON output etc.)

Are these fields being omitted on purpose and PHP just adds them when it performs the query using PDO with FETCH_OBJ turned on? If yes why is it that we do not explicitly put the fields in the model? Doesn't it help us to know what fields we have, and also IDEs such as PHPStorm to pop up the right auto-complete fields?

If they are actually required, what access level do they need to have?

Thanks.

like image 437
jbx Avatar asked Sep 30 '14 01:09

jbx


People also ask

How can I get specific field in Laravel?

Select specific columns with Laravel Eloquent To get all of the columns from the users table, we would use the following: $user = User::where('username', 'bobbyiliev')->get(); However, if you wanted to get only a specific column, you could pass it as an argument to the get() method.

What is fillable attribute in a Laravel model?

In eloquent ORM, $fillable attribute is an array containing all those fields of table which can be filled using mass-assignment. Mass assignment refers to sending an array to the model to directly create a new record in Database.

Why we use fillable in model in Laravel?

The fillable property is used inside the model. It takes care of defining which fields are to be considered when the user will insert or update data. Only the fields marked as fillable are used in the mass assignment. This is done to avoid mass assignment data attacks when the user sends data from the HTTP request.


1 Answers

Column names (fields) are not required in Eloquent models. As you pointed out, it is only necessary to define the functions which determine the relationships that a model has with others.

It isn't necessary to include them, because of the reason you mentioned (Laravel does a select * and then adds all of the returned rows to the model object as public properties). This is a process dubbed hydration and you can see exactly what is happening by digging into the Laravel source. Here's a summary of what happens:

  1. You call (for example), Users::find(123);
  2. Illuminate\Database\Eloquent\Model::find() calls Illuminate\Database\Eloquent\Builder::find()
  3. find() constructs the SELECT * FROM users WHERE id = 123 query and then returns the first result by calling Illuminate\Database\Eloquent\Builder::first()
  4. first() adds LIMIT 1 by calling Illuminate\Database\Query\Builder::take()
  5. Then first() sets the columns to be retrieved (* by default) by calling Illuminate\Database\Eloquent\Builder::get().
  6. get() returns an Illuminate\Database\Eloquent\Collection by using the return value of Illuminate\Database\Eloquent\Builder::getModels()
  7. getModels() actually performs the query and then calls Illuminate\Database\Eloquent\Model::newFromBuilder() for each row returned
  8. newFromBuilder() creates a new instance of the model and sets the columns (fields) by calling Illuminate\Database\Eloquent\Model::setRawAttributes()

I've omitted some unrelated things such as eager loading to simplify the process, but this is basically what happens for each query.

You make a good point that knowing the fields beforehand can be helpful for autocompletion. Because of the nature of setRawAttributes() it is perfectly OK to declare all column names (fields) in your model (just make sure they are public). The convention, though (and for you sanity), is to omit them. Such declarations should be left to migration files.

After further examination of the source, it is not ok to declare the fields beforehand. This is because the actual attribute values are stored in an $attributes property and then accessed by the magic method __get(). The trouble here is that by defining the properties beforehand, you will prevent __get() from being called when you access the fields. Therefore, this is not an option.

However, there are ways to hint to editors (like PhpStorm) about the existence of properties without explicitly defining them.

like image 145
Bailey Parker Avatar answered Oct 16 '22 13:10

Bailey Parker