phplaravelmodel

Laravel: Unique foreign key per another foreign key (user_id)


I have a UserCategoryFollows table which has a user_id related to Users and a category_id related to Categories.

Users can follow any amount of Categories, but I don't want to insert multiple rows for the same category_id and user_id.

For example, I don't want this in my database:

user_id     category_id
1           2
2           1
2           3
1           4
2           1   <---- Duplicate
1           2   <---- Duplicate

Is this something I can validate inside the Model or is this validation done via controllers?

I'm currently seeding:

public function run()
    {

        $catCount = App\Category::count();
        $faker = \Faker\Factory::create();
        $follows = [];

        for ($i = 0; $i < 100; $i++) {
            $user_id = App\User::all()->random()->id;
            $category_id = $faker->numberBetween(1, $catCount);

            $follow = [
                'user_id' => $user_id,
                'category_id' => $category_id
            ];


                array_push($follows, $follow);



        }



        foreach ($follows as $follow) {
            App\UserCategoryFollow::create($follow);
        }

    }

I could alter my array to pluck out duplicates, but I think it would be better to handle on the model if possible.


Solution

  • Initially, you want to add this line to your migration file (this step is optional but it is better to implement it to ensure data integrity)

    $table->unique(['user_id', 'category_id']);
    

    Secondly, use firstOrCreate based on your user_id and category id to automatically avoid inserting non-unique values

        for ($i = 0; $i < 100; $i++) {
            $user_id = App\User::all()->random()->id;
            $category_id = $faker->numberBetween(1, $catCount);
            App\UserCategoryFollow::firstOrCreate( ['user_id' => $user_id,'category_id' => $category_id]);
        }