Home > Mobile >  Laravel database relationship in migration vs in class - Confused - Both of them are need?
Laravel database relationship in migration vs in class - Confused - Both of them are need?

Time:09-06

I am confused about Laravel database relationship (unsigned id, foreign references, cascade).

Do I have to use relationship in class (like hasMany, hasOne) and in table migration (like foreign, references); for both of them too?

I had read some articles but they are not clear for me. what is the best way for best developing on an example?

As an example for category and blog post; how should it be or your best example please?

create_categories_table migration:

public function up()
{
    Schema::create('categories', function (Blueprint $table) {
        $table->id();
        $table->string('name');
        $table->string('slug');
        $table->timestamps();
    });
}

create_posts_table migration:

public function up()
{
    Schema::create('posts', function (Blueprint $table) {
        $table->id();
        $table->string('title');
        $table->string('slug');
        $table->longText('description');
        $table->timestamps();
    });
}

and Post Model:

public function category()
{
    return $this->belongsTo(Category::class);
}

thank you.

CodePudding user response:

The role of migrations is to build your database schema (INSERT TABLE, ALTER TABLE, FOREIGN KEYS, DROP COLUMN, etc...).

The role of relations in Eloquent Model is to make Model aware of relations with other models. It provides a convenient way to query related models. Relations will not create foreign keys for you.

For example if a post can be in only one category and a category contains many posts :

public function up()
{
    Schema::create('categories', function (Blueprint $table) {
        $table->id();
        $table->string('name');
        $table->string('slug');
        $table->timestamps();
    });
}

public function up()
{
    Schema::create('posts', function (Blueprint $table) {
        $table->id();
        $table->unsignedInteger('category_id');
        $table->string('title');
        $table->string('slug');
        $table->longText('description');
        $table->timestamps();
    
        $table->foreign('category_id')->references('id')->on('categories');
    });
}

Then, in your Post model :

public function category()
{
    return $this->belongsTo(Category::class);
}

If you need you can also add this to Category Model :

    public function posts()
    {
        return $this->hasMany(Post::class);
    }

This will allow you to easily retrieve all posts of a category for example :

    public function getPostsByCategory(int $categoryId) 
    {
        $posts = Category::find($categoryId)->posts()->get();

        return $posts;
    }

CodePudding user response:

Technically you don't have to define relationships between related data in your database, however, it is good practice to do so and provides benefits such as data integrity and cascading. There are also tools that can reverse engineer your database to generate a visual representation of its structure including relationships if they have been defined.

Adding relationships in your migration files creates that relationship at the database level, informing the engine that there is a logical relationship between data. You can define a foreign key constraint in your migrations in many ways, however, as of Laravel 7.x there is a forieignId method and a constrained method providing a simplified way of defining relationships from the previous method.

So for a basic example, to define a simple one-to-one relationship you might do:

public function up()
{
    Schema::create('child', function (Blueprint $table) {
        $table->foreignId('parent_id')->constrained();
    });
}

Similarly, using Eloquent relationships to define relationships at the application level is not required. However, these helper methods provide a consistent and simplified implementation for managing related data that would otherwise require you to write additional code.

At least one but ideally both of the above would be used.

  • Related