i have 3 tables shops , business_categories , shop_categories as below
Business Categories holds has all the categories
Shop has shops data
Shop categories has ids for shops and businiess categories which are assigned to shop
I need to list the category names with shop listing. i am able to get categories but not sure how can i relate 3rd table
in my Shop Model
public function shopCategories(){
return $this->belongsTo(ShopCategory::class,'shop_id','shop_id');
}
In my controller
Shop::with('shopCategories')->get()
this returns me shops and data from shop_categories table but i am not sure how can i relate shop_categories to business_categories table
Edit ::
business_categories
shop_categories
shop
basically you have classic Many-To-Many relation between Shop and BusinessCategory models (each shop can have many categories and category can have many shops), so
in table shop_categories you don't need field shop_category_id as intermidiate tables mostly don't use primary keys
defining standard many-to-many relation
//Shop model
public function categories() {
return $this->belongsToMany(BusinessCategory::class, 'shop_categories', 'business_category_id', 'shop_id');
}
//BusinessCategory model
public function shops() {
return $this->belongsToMany(Shop::class, 'shop_categories', 'shop_id', 'business_category_id');
}
now when relation is set in controller you may do
$categoriesWithShops = BusinessCategory::with('shops')->get();
and get desired categories with shops listing
this way don't makes you to drop ShopCategory model and stop using it (if needed), but explores some beautiful things like sync, toggle etc for defined relation
Use laravel Has Many Through relation model:
In your shop categories model:
public function shopCategories()
{
return $this->hasManyThrough(
Shop::class,
business_categories::class,
'shop_id', // Foreign key on the shop table...
'business_category_id', // Foreign key on the business table...
'id', // Local key on the shop table...
'id' // Local key on the business table...
);
}
Related
I have a table named categories and here is it's structure:
id bigint(20) AUTO_INCREMENT
name varchar(255)
description varchar(255)
short_name varchar(255)
picture varchar(255)
parent_category int(11)
category_type tinyint(4)
So each category has a category_type which can be one of these values:
1: Main Category
2: Superior Category
3: Secondary Category
4: Secondary Sub Category
Now I wanted to set a One To Many relationship between these categories.
For example: a main category has many superior categories and a superior category is related to one main category.
And this will apply to the rest of them as well.
But because I have only one Model which is Category, I don't know how to apply this relationship, so if you know, plz help me out...
Model Category.php:
class Category extends Model
{
use HasFactory;
protected $fillable = ['name','short_name','description','picture','category_type','parent_category'];
}
You can write the following relations in the Category model:
public function parentCategory()
{
return $this->belongsTo(Category::class, 'parent_category', 'id');
}
public function childCategories()
{
return $this->hasMany(Category::class, 'parent_category', 'id');
}
You can later fetch the relations for example like this:
$cat = Category::where('category_type', 'main')->first();
$cat->childCategories; //all the categories where the main category has been set as parent category
Or
$cat2 = Category::where('category_type', 'secondary')->first();
$cat2->parentCategory; //the category object which has been marked as parent for that specific secondary category
If you want to filter per category type on the relations, you can do this as well:
public function superiorChildCategories()
{
return $this->hasMany(Category::class,'parent_category','id')->where('category_type','superior');
}
To use:
$cat3 = Category::where('category_type', 'main')->first();
$cat3->superiorChildCategories; //all the superior type categories where the main category has been set as parent category, will return null if there is no superior type child categories
Don't forget to set the actual parent type relation on the database as well, so parent_category column should be the id of the parent category.
It is also tested, and works as expected.
As I know, Laravel relationships work between models and not within one model. I would recommend you to use separate models (and separate tables).
If all other categories are on the same level and they all belong to one main category, you can make one model for the main category and all others can have one model.
public function parent_category()
{
return $this->hasMany(Category::class,'parent_category','id');
}
I am new to laravel & want to implement eloquent relationship.
Let me explain.
Consider I have 2 tables
products
product_id
product_name
brand_id
price
brands
id
brand_name
Each product will have one brand Id.But in Brands table, there is no product id. One brand_id can be in multiple product rows, and one product has one brand_id only. I want to select some col from products table plus brand_name with respect to brand_id of products table using Model.SO in Product model I wrote:
public function brands()
{
return $this->hasOne('App\Brand','product_id');
}
and in Brand model I write:
public function products()
{
return $this->belongsTo('App\Product','brand_id');
}
Now I want the result:
product_name
price
brand_name
How can I fetch those data in controller using eloquent relation? Also, the way I wrote Model relationship, Is it ok??
Your Product Model relation will be below
public function brand(){
return $this->belongsTo('App\Brand','brand_id');
}
public function product(){
return $this->belongsTo('App\Product','product_id');
}
Now in controller you can add query as below.
$products = Product::with('brand','product')->get();
echo '<pre>'
print_r($products->toArray());
exit;
It looks to me like you want a one-to-many relationship, so one brand can have many products and many products belong to one brand.
Product model:
public function brand()
{
return $this->belongsTo('App\Brand');
}
Brand model:
public function products()
{
return $this->hasMany('App\Product');
}
Then you would be able to get the brand information like this:
The full brand model:
Product::first()->brand
The brand name:
Product::first()->brand->brand_name
From the docs:
A one-to-many relationship is used to define relationships where a
single model owns any amount of other models. For example, a blog post
may have an infinite number of comments.
P.S.:
Your table column names do not make much sense to me, why do you have product_id on products but then on brands it is just called id? Why do you have product_name but then just price? why is it not just name or product_price, so your at least consistent?
There are 3 models:
First (first_id)
Connection (connection_id, first_id, product_id)
Second (second_id, product_id)
I would like to connect the three models together using laravel relationships
First->joined to Connection though first_id
Connection->joined to First through first_id, & joined to Second through product_id
Second -> joined to Connection through product_id
So: First joined to Second through Connection first_id, product_id
Is this possible to do using something like HasManyThrough?
Thanks for your time
On your First model:
public function second () {
return $this->hasManyThrough(
Second::class,
Connection::class,
'product_id', // Foreign key on connection table
'product_id', // Foreign key on second table
'first_id', // Local key on first table
'first_id' // Local key on connection table
);
}
Based on your description the column names should work.
In tinker you can validate if it's hooked up correctly by doing something like First::first()->second.
It depends on what type of relationship Your first model and second model shares as well as what type of relation second and third model shares.
if consider your first model First and second model Second shares a one-to-one relation, as well as Second model and Third models shares one-to-one relationships.
It will be $first->second->third; //no has many through relationship requires
If your First model and Second models shares as hasMany-belongs to relation than you need to use hasManyThrough relationship
example from doc
class Country extends Model
{
public function posts()
{
return $this->hasManyThrough(
'App\Post',
'App\User',
'country_id', // Foreign key on users table...
'user_id', // Foreign key on posts table...
'id', // Local key on countries table...
'id' // Local key on users table...
);
}
}
You can try using nested relationships.
Nested Eager Loading
To eager load nested relationships, you may use "dot" syntax. For example, let's eager load all of the book's authors and all of the author's personal contacts in one Eloquent statement:
$books = App\Book::with('author.contacts')->get();
Book Model:
public function author()
{
return $this->hasOne('App\Author');
}
Author Model:
public function contacts()
{
return $this->hasMany('App\Author');
}
Documentation:
https://laravel.com/docs/5.8/eloquent-relationships
I have the following models
Category
id // we don't want to use this one for the relation
category_id // we want to use this
Product
id
CategoryProduct
product_id // points to "id" on products table
category_id // points to **category_id** on categories table
I have the Product model set up as follows (only the most recent variation).
class Product {
public function categories() {
return $this->belongsToMany('Category', 'categories_products', 'category_id');
}
}
When I try to get a product with categories as follows...
Product::with('categories')->get();
I either get the wrong categories because the query is using id on categories as the foreign key. I need it to be using category_id on the categories table.
Or I get none at all. I can't seem to hash out how to set up which columns to use on the belongsToMany method.
Try this follow,
class Product {
public function categories() {
return $this->belongsToMany('Category', 'categories_products', 'product_id','category_id');
}
}
Please any help me that how i pull all the fields from both tables in laravel many to many relationship.
I have two table
categories
id
cname
ctitle
description
products
id
pname
ptitle
pdescription
price
and bridge table
products_to_categories
id
category_id
product_id
So i have pull all the fields from both tables based on product id.
UPD: As commented patricus, the "bridge" table should be called "category_product"
First, you should define the "belongsToMany" relationship in the Product model:
// ...
class Product extends Eloquent {
// ...
function categories()
{
return $this->belongsToMany('Category');
}
}
After it you should load the product by id:
$product = Product::find($product_id);
And now you can access its categories through the "categories" property:
foreach($product->categories as $category)
{
// do what you want with the $category
}
Official docs for M2M relationships:
http://laravel.com/docs/4.2/eloquent#many-to-many