Skip to main content

Multi-Select and belongsToMany Relationship

Premium
5 min read

In this lesson, we will see how to create multiple select input. We will change a category select dropdown from a single select to a multiple one.

multiple select form


DB Changes

Before making changes to the Livewire component, we need to make changes to the DB. First, we need a BelongsToMany relationship table.

database/migrations/xxxx_create_category_product_table.php:

Schema::create('category_product', function (Blueprint $table) {
$table->foreignId('category_id')->constrained()->cascadeOnDelete(;
$table->foreignId('product_id')->constrained()->cascadeOnDelete();
});

app/Models/Product.php:

use Illuminate\Database\Eloquent\Relations\BelongsToMany;
 
class Product extends Model
{
protected $fillable = [
'name',
'description',
'category_id',
'color',
'in_stock',
];
 
const COLOR_LIST = [
'red' => 'Red',
'green' => 'Green',
'blue' => 'Blue',
];
 
public function category(): BelongsTo
{
return $this->belongsTo(Category::class);
}
 
public function categories(): BelongsToMany
{
return $this->belongsToMany(Category::class);
}
}

Earlier, we added category_id to the Products table. You need to delete that migration. Otherwise, when creating a product, you will get an error. Don't forget to change the ProductFactory accordingly.

Also, I have changed the seeder to add two categories for each product.

$categories = collect(Category::pluck('id'));
Product::factory(50)
->create()
->each(function (Product $product) use ($categories) {
$product->categories()->sync($categories->random(2));
});

Livewire Component Changes

Now let's change the Products Livewire component to show multiple companies and fix...

The Full Lesson is Only for Premium Members

Want to access all of our courses? (36 h 00 min)

You also get:

61 courses
Premium tutorials
Access to repositories
Private Discord
Get Premium for $129/year or $29/month

Already a member? Login here

muuucho avatar

In Products/render(), should this line be deleted?

->when($this->searchCategory > 0, fn(Builder $query) => $query->where('category_id', $this->searchCategory))
👍 3
Myhkail Mendoza avatar

Yes, I was wondering why sorting by category wasn't working for me.

Joe avatar

There's a little typo in the first migration, the closing brackets are missing:

Schema::create('category_product', function (Blueprint $table) {
$table->foreignId('category_id')->constrained()->cascadeOnDelete(;
$table->foreignId('product_id')->constrained()->cascadeOnDelete(;
});
Marcelo de Azevedo avatar

This relationship:

public function categories(): BelongsToMany
{
return $this->belongsToMany(Category::class);
}

Returns nothing when run on:

$products = Product::with('categories) ->when($this->searchQuery !== '', fn(Builder $query) => $query->where('name', 'like', '%'. $this->searchQuery .'%' )) ->when($this->searchCategory > 0, fn(Builder $query) => $query->where('category_id', $this->searchCategory)) ->when($this->searchCategory > 0, function (Builder $query) { $query->whereHas('categories', function (Builder $query2) { $query2->where('id', $this->searchCategory); }); }) ->paginate(10);

I put a dd($products) and the product returns, however the relationship is empty. Couldn't you make the code available on GitHub so I can see what's wrong?

Marcelo de Azevedo avatar

I found the problem, but in any case I could make the code available on Git

We'd Love Your Feedback

Tell us what you like or what we can improve

Feel free to share anything you like or dislike about this page or the platform in general.