Laravel has-many-through with multiple intermediate tables - laravel

I am trying to develop multiple-shop eCommerce platform.
So the following tables created:
shops: id, name, ...
products: id, shop_id, ...
orders: id, ...
order_details: id, order_id, product_id, ...
And this is the summery of my models' relationships:
Shop->products: Shop hasMany Product
Product->shop: Product belongsTo Shop
Order->details: Order hasMany OrderDetail
OrderDetail->order: OrderDetail belongsTo Order
OrderDetail->product: OrderDetail belongsTo Product
Product->orders: Product hasMany OrderDetail
Now, 1: Is it possible to define Shop->orders relationship?(It seams has-many-through not works in this case due to multiple intermediate tables)
2: If it is possible, could the shop->orders->details contains only the records related to shop products?
It should be note that each Order may contain products from multiple shops but the shop->orders->details relation should contains only the shop products.

There is no native relationship for this case.
I created a HasManyThrough relationship with support for BelongsToMany: Repository on GitHub
After the installation, you can use it like this:
class Shop extends Model {
use \Staudenmeir\EloquentHasManyDeep\HasRelationships;
public function orders() {
return $this->hasManyDeep(Order::class, [Product::class, 'order_details']);
}
}

Related

Creating a "through" relationship when both foreign keys are on the same table

I have a products table. A product belongs to a category and a country.
I would like to find out what countries a category has by leaning on this relationship.
I've considered hasManyThrough and https://github.com/staudenmeir/belongs-to-through but this is sort of a belongsTo relationship, with both foreign keys on an intermediate table, I suspect the products table is sort of acting like a pivot.
I would like to know how I can set up a relationship that relates categories to countries through the products table - is this possible?
Tables:
Categories
id
title
Countries
id
title
Products
id
title
category_id
country_id
Relationships:
A product belongs to a country / A country has many products.
A product belongs to a category / A category has many products.
You've pretty much described a Many to Many relationship with Product being the pivot table.
# Category model
public function countries()
{
return $this->belongsToMany(Country::class, 'products')
->withPivot(['id', 'title']); // optional
}
# Country model
public function categories()
{
return $this->belongsToMany(Category::class, 'products')
->withPivot(['id', 'title']); // optional
}

Eloquent order model by its relationship hasManyTrough

I have 3 tables
products, product_categories and categories
product_categories is a pivot table that help me on the relationship between products & categories.
The relation is as follow in Product.php model:
public function categories() {
return $this->hasManyThrough(Category::class, ProductCategory::class, 'product_id', 'id', 'id', 'category_id');
}
So now I need to query the products so I am doing the following:
Product::with('options')
->with('options.price')
->with('categories')
->paginate(25);
I can not find the way to sort my products list by the category name on the categories table...
is there any way?
My products table is quite large so it wont be possible to get all the results first and then sortBy()->take(25);
EDIT
The categories table has multiple categories and subcategories... the product_categories relate products with only subcategories...
Basically what I want is to sort the products by the main category

How to get data from third table in eloquent relationships eloquent many to many relationship

I am using Eloquent ORM and I have Book model which connect to BookCategory model and BookCategory connect to Category. The l'm problem facing is how to include data from third table in eloquent relationships?
Book
id
name
Category
id
name
type
BookCategory
id
book_id
category_id
Lets say for example you want to get all the books of a certain category:
assuming your pivot table name is Book_Category
in your Category model:
public function books()
{
return $this->belongsToMany('App\Models\Book', 'Book_Category', 'category_id', 'book_id');
}
and you can eager load category books like :
$categories = Category::get()->load('books');
//OR
$categories = Category::with('books')->get();
If I understand you right, you are looking for the pivot attribute. This makes additional columns of the intermediate table available.
https://laravel.com/docs/8.x/eloquent-relationships#retrieving-intermediate-table-columns

Laravel: how to sort a collection with hasMany field

I have five tables:
details having fields id, name and has hasMany relation with contributions.
purpose having fields id, name and has hasMany relation with contributions.
period having fields id, name and has hasMany relation with contributions.
user having fields id, name and has hasMany relation with contributions.
and
contributions having id, amount and "belongsTo" relation with user_id, detail_id, purpose_id, period_id
Now, I want to get all contributions of a specific user (filtered by user_id) and then sort the result by period.name, detail.name and purpose.name.
Any suggestions?
The question has been identified as possible duplicate of Laravel orderBy on a relationship . However there is a basic difference.
there, there is relation between user and comment & user and post. however in my case, there isn't any relation between user and details/purposes/periods tables.
<?php
class User
{
public function comments()
{
return $this->hasMany('Comment');
}
}
is possible in that case, but by same analogy, in my case, class User doesn't have any details() function to get hasMany relations. My user has relation with only contributions table and contributions table has relations with details purpose etc tables.
hope I am able to clarify the difference.

Have 2 one to one relationships between the same models

I have a User model & a Sale model. A User can be either a Merchant or Customer.
When a sale is made the sale belongs to a merchant but also to a customer.
I figured I can give the sale a merchant_id & a sale_id and create 2 different relationships in the models.
Just didn't feel right to me. So my question is there a better way to go about this? I'm in a early stage of development. I wouldn't mind changing the database around a bit.
I'm using laravel 5.3
It's not one-to-one, it's many-to-many relationship and sales table should be a pivot table. Relation usually looks like this:
class User extends Authenticatable
{
public function customers()
{
return $this->belongsToMany('App\User', 'sales', 'customer_id', 'merchant_id');
}
Where customer_id and merchant_id are foreign keys pointed to id in users table.
If you do a lot of stuff with sales table, just keep using Sale model for this pivot table.

Resources