Laravel belongs to many by two intermediate tables? - php

Hi guys I have to create many to many relationship but through a another table. but laravel BelongsToMany give only 1 intermediate table relation
here table structure:
features Table:
+----+-----------+
| id | text |
+----+-----------+
| 1 | feature 1 |
+----+-----------+
| 2 | feature 2 |
+----+-----------+
feature_values table:
+----+-----------+-------+
| id | feature_id | text |
+----+-----------+-------+
| 1 | 1 | val 1 |
+----+-----------+-------+
| 2 | 1 | val 2 |
+----+-----------+-------+
| 3 | 2 | val 3 |
+----+-----------+-------+
products table:
+----+-------+
| id | name |
+----+-------+
| 1 | tv |
+----+-------+
| 2 | phone |
+----+-------+
product_features table:
+----+------------+------------+
| id | product_id | feature_id |
+----+------------+------------+
| 1 | 1 | 1 |
+----+------------+------------+
| 2 | 2 | 1 |
+----+------------+------------+
| 3 | 2 | 2 |
+----+------------+------------+
product_feature_values table:
+----+--------------------+------------------+
| id | product_feature_id | feature_value_id |
+----+--------------------+------------------+
| 1 | 1 | 1 |
+----+--------------------+------------------+
| 2 | 2 | 1 |
+----+--------------------+------------------+
| 3 | 2 | 2 |
+----+--------------------+------------------+
I'm trying to create a relationship between feature_values and and products through product_feature_values and product_features for get product by feature_values.
I know data can obtain by joining tables, but I looking for a solution that using by laravel model relationships
thank you.
I tried like this
class FeatureValue extends Model
{
public function products()
{
return $this->belongsToMany(Product::class,'product_feature_values')->withTimestamps();
}
}

I'm afraid, that Laravel didn't offer that out-of the box. But there's a package called staudenmeir/belongs-to-through that does.

Related

laravel how to get related data from another table with no relation

I am working on laravel and i have the following table structure
elments table
+----+--------------+------------+--------+
| id | element | category | cities |
+----+--------------+------------+--------+
| 1 | element 1 | 1 | 1,2,3 |
| 2 | element 2 | 2 | 2,3 |
+----+-----------+---------------+--------+
cities table
+----+-----------+
| id | city |
+----+-----------+
| 1 | city 1 |
| 2 | city 2 |
| 3 | city 3 |
+----+-----------+
categories table
+----+-------------+
| id | category |
+----+-------------+
| 1 | category 1 |
| 2 | category 2 |
| 3 | category 3 |
+----+-------------+
I use the eloquent query with relations as following
$elements =Element::with('categories')->get();
but how to get cities names for each elements from the cities table in the same query

Laravel eloquent sorts data from largest to smallest from table relations that do not necessarily have a relationship

I've a problem when sorts data from largest to smallest from table relations that do not necessarily have a relationship with PHP Laravel Eloquent.
Table: items
|---------------------------|
| id | name | price |
|---------------------------|
| 1 | Samsung | 70.000 |
| 2 | iPhone | 90.000 |
| 3 | Nokia | 50.000 |
| 4 | Huawei | 80.000 |
| 5 | Xiaomi | 60.000 |
| 6 | LG | 40.000 |
|---------------------------|
Table: sells
|------------------------------------------|
| id | invoice | total | created_at |
|------------------------------------------|
| 1 | 1001 | 720.000 | 2021-10-01 |
| 2 | 1002 | 420.000 | 2021-10-01 |
| 3 | 1003 | 80.000 | 2021-10-15 |
|------------------------------------------|
Table: sell_items
|------------------------------------|
| id | sell_id | item_id | qty |
|------------------------------------|
| 1 | 1 | 1 | 5 |
| 2 | 1 | 2 | 4 |
| 3 | 2 | 3 | 3 |
| 4 | 2 | 2 | 3 |
| 5 | 3 | 4 | 1 |
|------------------------------------|
and I will only take 5 data from the largest.
Top Product:
|--------------------------------|
| No | Product | Total (Qty) |
|--------------------------------|
| 1 | iPhone | 7 |
| 2 | Samsung | 4 |
| 3 | Nokia | 3 |
| 4 | Huawei | 1 |
| 5 | Xiaomi | 0 |
|--------------------------------|
My syntax:
$thisYear = date('Y');
$topProduct = SellItem::whereHas('sells', function($p) use ($thisYear) {
$p->whereYear('created_at', $thisYear)
})
->whereHas('items')
->select('id', 'name', DB::raw('sum('qty') as total'))->take(5)->orderBy('total', 'desc')->get();
please help me to solve it.
Assumptions:
SellItem is a model for the pivot table sell_items
Item is a model on table items
Sell is a model on table sells
SellItem has a BelongsTo relationship item with Item
SellItem has a BelongsTo relationship sell with Sell
With the relationships set in the model classes, you can do something like this:
$topProducts = SellItem::has('item')
->with('item')
->whereHas('sell', function ($query) {
$query->whereYear('created_at', date('Y'));
})
->groupBy('item_id')
->withSum('qty as total')
->orderByDesc('total')
->get();
->map( function ($sell) {
return $sell->item;
});

How to get id's of those with empty values as well as filled values using inner join in mysql

$products = Product::select('products.*','c.name as category_name','b.name as brand_name')
->join('categories as c','products.category_id','c.id')
->join('brands as b','products.brand_id','b.id')
->whereNull('products.deleted_at')
->orderBy('products.created_at','desc')
->get()
->toArray();
The above is the code I am using in laravel to get product details from product table. With the above code I am getting all the products with having brand_id, but I want both products having brand_id as well as without brand_id (shown in table below) using join.
Below is the product table:-
---------------------------------------------------------------------------
| id | category_id | sub_category_id | brand_id | title |
---------------------------------------------------------------------------
| 1 | 3 | 1 | 1 | abc |
---------------------------------------------------------------------------
| 2 | 3 | 3 | 2 | Shirts |
---------------------------------------------------------------------------
| 3 | 3 | 3 | | jeans |
---------------------------------------------------------------------------
| 4 | 1 | 1 | | efg |
---------------------------------------------------------------------------
Below is the brand table:-
--------------------------------------------------------------
| id | category_id | sub_category_id | name |
--------------------------------------------------------------
| 1 | 3 | 1 | abc |
--------------------------------------------------------------
| 2 | 3 | 3 | efg |
--------------------------------------------------------------
Below is the Category Table:-
-------------------
| id | name |
-------------------
| 1 | men |
-------------------
| 2 | women |
-------------------
| 3 | kids |
-------------------

How to query a closure table to get descendants

I have two tables category and hierarchy
table schema for category:
+----+---------+
| id | name |
+----+---------+
| 1 | Shoes |
| 2 | Sandals |
| 3 | floaters|
| 4 | men |
| 5 | women |
+----+---------+
table schema for hierarchy
+----------+------------+
| ancestor | descendant |
+----------+------------+
| 1 | 1 |
| 1 | 2 |
| 1 | 3 |
| 2 | 4 |
| 2 | 5 |
+----------+------------+
How to query to get the data in below order
-Shoes
- Sandals
-men
-women
- floaters
I have tried but am new to such complex queries.

Laravel 5.1 Eloquent with() and max() using multiple has-many relationships

I'm trying to use Eloquent to find the max value of a column on the last table of a multiple has-many relationship.
Given the following table structure.
Buildings
+----+---------------+
| id | building_name |
+----+---------------+
| 1 | Building 1 |
| 2 | Building 2 |
+----+---------------+
Rooms
+----+-----------+-------------+
| id | room_name | building_id |
+----+-----------+-------------+
| 1 | Room 1 | 1 |
| 2 | Room 2 | 1 |
| 3 | Room 3 | 2 |
+----+-----------+-------------+
maintenancelog
+----+-------------------+---------+---------------------+
| id | maintenance_value | room_id | timestamp |
+----+-------------------+---------+---------------------+
| 1 | Cleaned | 1 | 2015-09-06 00:54:59 |
| 2 | Cleaned | 1 | 2015-09-06 01:55:59 |
| 3 | Cleaned | 2 | 2015-09-06 02:56:59 |
| 4 | Cleaned | 2 | 2015-09-06 03:57:59 |
| 5 | Cleaned | 3 | 2015-09-06 04:58:59 |
| 6 | Cleaned | 3 | 2015-09-06 05:59:59 |
+----+-------------------+---------+---------------------+
I'd like to see if it's possible to generate an eloquent statement that would retrieve the building name, room name, and ONLY the LAST maintenance log date value.
The following works to give me a collection of ALL the values.
$buildings = Building::with('rooms.maintenancelog')->get();
but this errors out, and it looks like it's trying to call max(maintenancelog.timestamp) on the buildings table..
$buildings = Building::with('rooms.maintenancelog')->max('maintenancelog.timestamp')->get();
Error returned:
.....(SQL: select max(`maintenancelog`.`timestamp`) as aggregate from `buildings`)
Am I just asking too much from eloquent, and should I just use the basic query builder
Add the following relationship to the Rooms model...
public function latestMaintenance()
{
return $this->hasOne('App\Maintenancelog')->latest();
}
and change the Eloquent statement to..
$buildings = Building::with('rooms.latestMaintenance')->get();
referenced Getting just the latest value on a joined table with Eloquent

Categories