So I have this piece of code in a recent migration:
public function up(): void
{
Schema::table('chirps', function (Blueprint $table) {
$table->string('message');
$table->foreignId('user_id')->constrained()->cascadeOnDelete();
});
}
and I have this in my User model:
public function chirps():HasMany {
return $this->hasMany(Chirp::class);
}
I want to understand the difference between a model and a the actual database (which is generated by the migrations)
to me both the hasMany(Chirp::class) and foreignId('user_id')->constrained()->cascadeOnDelete(); seem to do the same thing (make a one to many relationship) but I have to repeat them manually.
I did my research and read online that a model provides nice methods to interact with the Database, but shouldn’t that be done automatically? i.e. the hasMany should itself create a user_id column. moreover it seems that whenever you do a schema upgrade like this you’re supposed to also make some changes to the models.
I am feeling that my mental model of how this side of backend dev works is a bit foggy and I’d love if someone would clear it up!
>Solution :
Migrations are only meant to create/modify the tables and columns in the database itself. You can use the foreign key constraints, but they aren’t required, and only the database knows about them. It’s a one-time thing, and only used when the migration commands are used. Migrations are Laravel’s nice way to modify the structure without manually running database commands, and keeps it consistent between development and production, like version control.
Models are Eloquent classes. This is what Laravel actually uses to interface with the database. It doesn’t alter the database structure at all, it just tells Laravel how the database is structured for Insert/Update/Delete queries.
Think of it this way. Say you have a User record, and the User can make posts, which then have comments. Your posts table will have a user_id foreign key, and your comments table will have a post_id foreign key, and probably have a user_id foreign key. If you were querying the database directly, you’d have to query each table separately, or use joins. With Eloquent models, you can have a User model with a hasMany Posts, and a Posts model with a hasMany comments, and a belongsTo User. If you want to retrieve a User with all of it’s posts and comments, you can do
User::with('posts','posts.comments')->find(1);
You still need to update your models when you alter the database so it knows how things are connected, because Laravel won’t detect it on its own.