I'm working on an Online Store project with Laravel 5.8 and in this project, I wanted to add "Add to favourites" ability for users to add a product to their favourite list.
So I created a Model like this:
class FavouriteProduct extends Model
{
protected $table = 'favourite_products';
protected $fillable = ['usr_id','prd_id'];
public function users()
{
return $this->belongsToMany(User::class, 'favourite_products', 'id', 'usr_id');
}
public function products()
{
return $this->belongsToMany(Product::class, 'favourite_products', 'id', 'prd_id');
}
}
And at the Product Model, I added this:
public function favourites()
{
return $this->belongsToMany(Product::class, 'favourite_products', 'prd_id', 'id');
}
And here is User Model:
public function favourites()
{
return $this->belongsToMany(FavouriteProduct::class, 'favourite_products', 'usr_id', 'id');
}
Now I wanted to make sure that I have set up the relationship correctly. So if you know this is correct or not, just let me know, I would really appreciate that...
CodePudding user response:
First, an option would be to delete your FavouriteProduct model BUT keep the favourite_products table. (Which would be my suggestion).
Or, you could also change the FavourteProduct to extend Pivot instead of Model and add ->using(FavouriteProduct::class) to both of the favourite relationships on User and Product.
I've gone into more detail with the two approaches below.
Option 1: Simple relationship
If you go with my first suggestion, you will need to make the following changes.
On your Product model, you need to add the following relationship:
public function favouritees()
{
return $this->belongsToMany(User::class, 'favourite_products', 'prd_id', 'usr_id');
}
On your User model, you need to add the following relationship:
public function favourites()
{
return $this->belongsToMany(Product::class, 'favourite_products', 'usr_id', 'prd_id');
}
This will now allow you to add favourites simply by doing something like the following:
$user = User::find($userId);
$product = Product::find($productId);
$user->favourites()->save($product);
Option 2: a more complex Pivot model
It would be best if you only used the pivot option if you intend to add additional information and relationships to the Pivot relation between the two models.
Like this on the Product model
public function favouritees()
{
return $this->belongsToMany(User::class, 'favourite_products', 'prd_id', 'usr_id')->using(FavouriteProduct::class);
}
Like this on the User model
public function favourites()
{
return $this->belongsToMany(Product::class, 'favourite_products', 'usr_id', 'prd_id')->using(FavouriteProduct::class);
}
But I suggest you start using a more Laravel standard approach; it comes with great benefits, including still being able to follow examples in the documentation when one is still learning.
Using columns such as usr_id and prd_id really makes no difference besides making your life harder. Had you used user_id and product_id, you wouldn't need to pass them to every relationship to tell Laravel that you decided to use your convention over Laravels. In the end, you are free to do so, and there are times when you inherit a database from elsewhere and become forced to do it.
CodePudding user response:
For example in your User Model: You are setting a relation with Product: so change the class:
public function favourites()
{
return $this->belongsToMany(Product::class, 'favourite_products', 'usr_id', 'product_id');
}
I'm not sure about the order of the keys.
CodePudding user response:
You can't have 2 this same named methods in two models! In User Model can be favourites(), but favourites() in Product Model allows to think thats product might have a favourite user. You should have a descriptive names to easier understanding your code. I learn many to many from this tutorial, I recommend it to you.
