Laravel migration default value
LaravelLaravel 5Laravel Problem Overview
I didn't understand what is the effect of the default
option in the migrations.
I can see that the column in the database is defined with default value, but the models are ignore it completely. Say I have a Book
model that reflect the books
table in the database. I have migration to create the books table:
Schema::create('books', function (Blueprint $table) {
$table->increments('id');
->string('author');
->string('title');
->decimal('price', 4, 1)->default(100);
->timestamps();
});
When I create a new instance of Book
model I see:
$book = new Book();
var_dump($book->price); //Always 0...
The default value is ignored and the attribute is not sets correctly. Ok, I can get it, because it is a new object and it shouldn't get the default values from the DB. But if I tries to save model like:
$book = new Book();
$book->author = 'Test'
$book->title = 'Test'
$book->save();
It is saves 0 in the field price
in the database!
So what is the point of the default
option in the migrations?
By the way... It wasn't be better if the model see inside the migration (if exists) what are the fields types and behavior instead to define it manually in the model and the migration? And moreover, even to create a validator automatically for the model. I think that it was possible with small change of the migration structure, so why it is not like that?
Laravel Solutions
Solution 1 - Laravel
Put the default value in single quote and it will work as intended. An example of migration:
$table->increments('id');
$table->string('name');
$table->string('url');
$table->string('country');
$table->tinyInteger('status')->default('1');
$table->timestamps();
EDIT : in your case ->default('100.0');
Solution 2 - Laravel
In Laravel 6 you have to add 'change' to your migrations file as follows:
$table->enum('is_approved', array('0','1'))->default('0')->change();
Solution 3 - Laravel
You can simple put the default value using default(). See the example
$table->enum('is_approved', array('0','1'))->default('0');
I have used enum here and the default value is 0.
Solution 4 - Laravel
Might be a little too late to the party, but hope this helps someone with similar issue.
The reason why your default value doesnt't work is because the migration file sets up the default value in your database (MySQL or PostgreSQL or whatever), and not in your Laravel application.
Let me illustrate with an example.
This line means Laravel is generating a new Book instance, as specified in your model. The new Book
object will have properties according to the table associated with the model. Up until this point, nothing is written on the database.
$book = new Book();
Now the following lines are setting up the values of each property of the Book
object. Same still, nothing is written on the database yet.
$book->author = 'Test'
$book->title = 'Test'
This line is the one writing to the database. After passing on the object to the database, then the empty fields will be filled by the database (may be default value, may be null, or whatever you specify on your migration file).
$book->save();
And thus, the default value will not pop up before you save it to the database.
But, that is not enough. If you try to access $book->price
, it will still be null (or 0, i'm not sure). Saving it is only adding the defaults to the record in the database, and it won't affect the Object you are carrying around.
So, to get the instance with filled-in default values, you have to re-fetch the instance. You may use the
Book::find($book->id);
Or, a more sophisticated way by refreshing the instance
$book->refresh();
And then, the next time you try to access the object, it will be filled with the default values.
Solution 5 - Laravel
The problem you face is not about the migration file. The value turns into 0 every time because you didn't change $fillable on your model. When you forget to add recently added column to $fillable of its model, Laravel inserts 0.