I have 3 tabes categories, sub_categories & products
category table
---------------------
| id | category_name |
---------------------
sub_category table
--------------------------------------------
| id | category_id(FK) | sub_category_name |
--------------------------------------------
product table
-----------------------------------------------------------------
| id | sub_category_id(FK) | product_name | product_description |
-----------------------------------------------------------------
**How do I get product category name using hasOneThrough eloquent relationship ( or using any other relationship).
I tried this in product model **
public function category(){
return $this->hasOneThrough(
Category::class,
SubCategory::class
);
}
But it gives error: Unknown column 'sub_categories.product_id'
You can install this external package staudenmeir/belongs-to-through to add the relationship you need.
class Product extends Model
{
public function subCategory()
{
return $this->belongsTo(SubCategory::class);
}
public functoin category()
{
return $this->belongsToThrough(Category::class, SubCategory::class);
}
}
class SubCategory extends Model
{
public functoin category()
{
return $this->belongsTo(Category::class);
}
}
class Category extends Model
{
public function subCategories()
{
return $this->hasMany(SubCategory::class);
}
public functoin products()
{
return $this->hasManyThrough(Product::class, SubCategory::class);
}
}
If you need to access Category directly from Product, and want to use laravels functions like $product->category()->attach($category->id) etc, then you need this dependency to achieve that.
If you are ok with doing:
$product->subCategory->category;
// or
$product->subCategory->category()->attach($category->id);
Then you don't need the dependency and you can exclude the category relationship on the Product model.
Related
I am new to laravel and trying the following:
I have these tables:
disciplines: id | name
specialties: id | name
categories: id | name
discipline_specialty (pivot table): id | discipline_id | specialties_id
Discipline model:
public function specialties()
{
return $this->belongsToMany(Specialty::class);
}
Specialty model:
public function disciplines()
{
return $this->belongsToMany(Discipline::class);
}
My question is:
how can I relate (many to many) the categories to the pivot table discipline_specialty in order to access the category name with the discipline and specialty ids?
I had thought of an additional pivot table that linked category id and discipline_specialty id but I don't know if it's the best solution and how to do it. Do you have any suggestions? Any help is appreciated.
You can introduce a junction/pivot model that will relate these 3 relations as many-to-one/belongsTo and one-to-many/hasMany from Discipline/Speciality/Category.
Discipline Speciality Category
\\ || //
\\ || //
DisciplineSpecialityCategory
This DisciplineSpecialityCategory model will have following attributes or FKs
Table: discipline_speciality_category
discipline_id
speciality_id
category_id
Now you model definitions will be like
class Discipline extends Model
{
public function disciplineSpecialityCategory()
{
return $this->hasMany(DisciplineSpecialityCategory::class, 'id', 'discipline_id');
}
}
class Speciality extends Model
{
public function disciplineSpecialityCategory()
{
return $this->hasMany(DisciplineSpecialityCategory::class, 'id', 'speciality_id');
}
}
class Category extends Model
{
public function disciplineSpecialityCategory()
{
return $this->hasMany(DisciplineSpecialityCategory::class, 'id', 'category_id');
}
}
class DisciplineSpecialityCategory extends Model
{
public function discipline()
{
return $this->belongsTo(Discipline::class, 'id', 'discipline_id');
}
public function speciality()
{
return $this->belongsTo(Speciality::class, 'id', 'speciality_id');
}
public function category()
{
return $this->belongsTo(Category::class, 'id', 'category_id');
}
}
I want the details of product that are added to wishlist table. I'm getting the data from wishlist table but i want to establish relation from product and user model also so that i can get the details of the product. My table Structure is :
Wishlists table:
id | product_id | user_id
products table :
id | name | price
users table :
id | first_name | last_name | contact
Wishlist Model :
public function user(){
return $this->belongsTo(User::class);
}
public function product(){
return $this->belongsTo(Product::class);
}
Product Model :
public function wishlist(){
return $this->hasMany(Wishlist::class);
}
public function users()
{
return $this->belongsToMany(User::class);
}
Users Model :
public function wishlist(){
return $this->hasMany(Wishlist::class);
}
I'm getting data from wishlist table through this code but can't get data from product table :
return Wishlist::with('product')->where('user_id', auth()->id())->get();
product relation is returning null
I think it's better to use a Many To Many relationship. In this case, you don't need the Wishlist model.
Product.php
public function users()
{
return $this->belongsToMany(User::class,'wishlists');
}
User.php
public function products()
{
return $this->belongsToMany(Product::class, 'wishlists');
}
Then you can get the user's wishlist like this:
auth()->user()->products;
Consider I have the following table structures for tables countries, products and suppliers:
countries
------------------------
id
name
code
product
------------------------
id
name
price
suppliers
------------------------
id
name
A product can be sold in different countries but supplier of that product can be different. With that keeping in mind, I made a relations table to keep track of which supplier is delivering which product in which country:
relations
------------------------
country_id
product_id
supplier_id
Let's say I have a product A which I need to store in country US and CA but the suppliers for these countries are X and Y respectively. The structure would look something like this:
countries
-------------------------------
id | name | code
-------------------------------
1 | United States | US
2 | Canada | CA
product
-------------------------------
id | name | price
-------------------------------
1 | A | 3.99
suppliers
------------
id | name
------------
1 | X
2 | Y
relations
-------------------------------
country_id | product_id | supplier_id
-------------------------------
1 | 1 | 1
2 | 1 | 2
My question is how can I use Eloquent Relationships to this table since many-to-many relationships only work on two tables. Is there any other workaround regarding this? Or is there any other efficient way to implement this scenario?
Thank you for your help.
There is no built-in way to make a relation using three tables. Whenever I encounter something like this myself, the best solution seems to be to make an in-between model that has relations to the three tables.
So in your case, I would create a SupplierProduct that has the relations country, supplier and product.
i have also same scenario class have multiple DaysClassDetails
use this function in your parent model
public function classType()
{
return $this->hasMany('App\DaysClassDetails(middlemodel)');
}
and DaysClassDetails have multiple DaysClassTimeDetails
public function classTime()
{
return $this->hasMany('App\DaysClassTimeDetails(lastchildmodel)');
}
public function classType(){
return $this->belongsTo('App\ManageClass(parentmodel)');
}
As Jerodev suggested, I made an intermediate model SupplierProduct. Instead of making many-to-many relationships, I made one-to-many relationships with SupplierProduct and retrieved data using with functions to retrieve all data related to that record.
This is how my Models look like (database structure is same as described in question):
SupplierProduct.php
namespace App;
use Illuminate\Database\Eloquent\Model;
class SupplierProduct extends Model {
public function country() {
return $this->belongsTo(Country::class);
}
public function product() {
return $this->belongsTo(Product::class);
}
public function supplier() {
return $this->belongsTo(Supplier::class);
}
}
Country.php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Country extends Model {
public function products() {
return $this->hasMany(SupplierProduct::class)->with('product', 'supplier');
}
}
Product.php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Product extends Model {
public function products() {
return $this->hasMany(SupplierProduct::class)->with('country', 'supplier');
}
}
Supplier.php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Supplier extends Model {
public function products() {
return $this->hasMany(SupplierProduct::class)->with('country', 'product');
}
}
I have the following polymorphic relationship:
// User.php
public function regions()
{
return $this->morphedByMany('App\Region', 'relationship')->withPivot('relationship_level');
}
public function groups()
{
return $this->morphedByMany('App\Group', 'relationship')->withPivot('relationship_level');
}
The pivot table is as follows:
id | user_id | relationship_id | relationship_type | relationship_level
1 | 12 | 8 | App\Region | master
2 | 18 | 12 | App\Group | fan
Is there any way (preferably as scope) where I can get every user who has level "master" when this user can have many relationship level to many relationship_type.
Using the existing relationships:
User::whereHas('groups', function ($query) {
$query->where('relationship_level', 'master');
})->orWhereHas('regions', function ($query) {
$query->where('relationship_level', 'master');
})->get();
Using a pivot model and a new relationship (faster):
class Relationship extends \Illuminate\Database\Eloquent\Relations\MorphPivot
{
//
}
class User extends Model
{
public function relationships()
{
return $this->hasMany(Relationship::class);
}
}
User::whereHas('relationships', function ($query) {
$query->where('relationship_level', 'master');
})->get();
don´t get it why this error occurs when inserting a new zip-code and relate it to an existing company using laravels eloquent belongsToMany feature.
here is my setup:
Error
file: "...\vendor\laravel\framework\src\Illuminate\Database\Eloquent\Model.php"
line: 411
message: "postcode"
type: "Illuminate\Database\Eloquent\MassAssignmentException"
Insertcode
$postcode = new Postcode(array('postcode' => $data['plz']));
Company::find($data['id'])->postcodes()->save($postcode);
Company Model
class Company extends Eloquent {
public function postcodes()
{
return $this->belongsToMany('Postcode');
}
}
Postcode Model
class Postcode extends Eloquent {
public function companies()
{
return $this->belongsToMany('Company');
}
}
Table postcodes
| id | postcode |
Table company_postcode
| id | postcode_id | company_id |
Table companies
| id | name |
Does anybody know why this isn´t working?
The error says
MassAssignmentException
That is because you are trying to mass assign postcode
new Postcode(array('postcode' => $data['plz']));
So make sure you whitelist the postcode variable as being mass assignable
class Company extends Eloquent {
protected $fillable = array('postcode');
public function postcodes()
{
return $this->belongsToMany('Postcode');
}
}