Should i separate Pivot tables for each feature in laravel? - php

I'm building review product application where there are 3 database tables
- Review
- Categories
- Affiliates
At first i created a pivot table with 2 entries review_id & category_id & the sync was successfull. Later i added another column "affiliate_id" to the pivot table & the sync was successfull but with multiple entries. Let me explain
Here's my controller for review -
$result->affiliates()->sync($aff_ids);
$result->category()->sync($product);
The above code is creating sperate pivot entries -
Pivot Table -
+-----------+-------------+--------------+
| review_Id | category_id | affiliate_Id |
+-----------+-------------+--------------+
| 1 | null | 1 |
| 1 | 1 | null |
+-----------+-------------+--------------+
Is the above pivot table correct or should i create seperate pivot tables for affiliates & categories ?
If the pivot table is not correct & if there is no need for seperate pivot tables then what i want to achieve is -
+-----------+-------------+--------------+
| review_Id | category_id | affiliate_Id |
+-----------+-------------+--------------+
| 1 | 1 | 1 |
+-----------+-------------+--------------+
The affiliate_id column can have have multiple entries so final result i want is -
+-----------+-------------+--------------+
| review_Id | category_id | affiliate_Id |
+-----------+-------------+--------------+
| 1 | 1 | 1 |
| 1 | 1 | 2 |
| 1 | 1 | 3 |
+-----------+-------------+--------------+

use withPivot;
in Review Model class
public function category()
{
return $this->belongsToMany(Category::class)->withPivot('affiliate_id');
}
Then
foreach ($categories as $category) {
$category_id_array[$category->id] = ['affiliate_id' => $affiliate->id];
}
//Insert into offence_photo table
$review->category()->sync($category_id_array, false);//dont delete old entries= false

Related

Laravel edit pivot table directly

I have a database, carpark and car records are linked by car_park pivot table.
Some rows in my pivot table (car_park)
id | carpark_id | car_id | in_date | out_date
1 | 1 | 1 | 2020-01-01 | 2020-01-30
2 | 1 | 2 | 2020-02-01 | 2020-02-28
3 | 1 | 1 | 2020-03-01 | 2020-03-31
....
In my carpark model, I have following entry:
public function cars() {
return $this->belongsToMany('App\Admin\Cars')->withPivot(['id', 'in_date', 'out_date']);
}
Save I need to update pivot table row id 1, I am not able to use
$carpark->$cars()->updateExistingPivot($car_id, $in_date, $out_date );
because the above statement will update both row id 1 and 3.
How can I update the pivot table with the pivot table row id?
Using wherePivot to find out pivot id
$carpark->cars()->wherePivot('id',1)->update(['in_date'=>'','out_date '=>'']);

How to get data from 3rd level table using joins [Laravel]

I want to get quantity of the product which is stored in bd_product_item_ledgers using the primary key (ID) of bd_products
bd_products is linked to bd_product_ledgers
Then, bd_product_ledgers is linked to bd_product_item_ledgers
table: bd_products
---------------------------------------------------------------------------------
| id | name | description | image | created_at | updated_at
---------------------------------------------------------------------------------
| 1 | shoe | this is a shoe | 15243.jpg |
---------------------------------------------------------------------------------
table: bd_product_ledgers
---------------------------------------------------------------------------------
| id | product_id | cost | created_at | updated_at
---------------------------------------------------------------------------------
| 1 | 1 | 500.00 |
---------------------------------------------------------------------------------
table: bd_product_item_ledgers
---------------------------------------------------------------------------------
| id | product_ledger_id | quantity | created_at | updated_at
---------------------------------------------------------------------------------
| 1 | 1 | 200 |
---------------------------------------------------------------------------------
I can get the cost of the product because there is ID present there, but how can i get the quantity also?
Simple MySQL Query Or Laravel eloquent etc anything would be good.
Thanks!
create three models Product,Item,ledgers and define your relationship ledgers in product model and item in ledgers model than you can get data using with query like,
$data = Product::with('ledgers.item')->get();
I am not Sure but i have created demo project with thr following tables and enterd the data provided by you
ITS PURLY DB FACADE VERSION
[IF YOU NEED IN ELOQUENT WAY PLEASE SHARE
YOUR MODEL NAMES]
public function index()
{
$selctArray = [
'bd_products.name',
'bd_products.description',
'PRDLED.cost as productCost',
'PRDITLED.quantity as productQuantity',
];
$joinQuery = DB::table('bd_products')
->leftJoin('bd_product_ledgers as PRDLED','PRDLED.product_id','=','bd_products.id')
->leftJoin('bd_product_item_ledgers as PRDITLED','PRDITLED.product_ledger_id','=','PRDLED.id')
->select($selctArray)->get();
dd($joinQuery);
}
please comment below if it has not satisfied your requirement and improve your question

Database inheritance Laravel 5.4

I am looking forward to implement a website dealing with teachers, students and parents. In the database I made, I've created a user table and 3 children tables : teachers, students, parents.
See below the table structure
User table
+--------+----------+----------+-------+
| id (PK)| username | password | email |
+--------+----------+----------+-------+
| 1 | user1 | 123 | ... |
+--------+----------+----------+-------+
| 2 | user2 | 132 | ... |
+--------+----------+----------+-------+
| 3 | user3 | 321 | ... |
+--------+----------+----------+-------+
Student table
+---------------+--------------+
| users_id (PK) | class |
+---------------+--------------+
| 1 | highschool |
+---------------+--------------+
| 3 | middleschool |
+---------------+--------------+
Teacher table
+--------------+-------------------+---------------------+
| users_id (PK)| subscription_type | end_of_subscription |
+--------------+-------------------+---------------------+
| 2 | monthly | 2017-10-25 |
+--------------+-------------------+---------------------+
And the parents table also have a PK which corresponds to a user id.
I just started to learn laravel and I really wonder how could I handle this properly maybe with eloquent with Laravel 5.4.
I am giving you some hints I think you can do rest and as your question is not specific I am guessing you are thinking how can you relate/join tables, so
Create three model let say User, Student, Teacher.
In Student & Teacher model create a method like below
public function user()
{
return $this->hasOne(User::class, 'id', 'users_id');
}
Now you can query like :
$student = Student::find($id) ;
$name = $student->user->name;
$email = $student->user->email ;
Or
$teachers = Teacher::where('subscription_type', 'monthly')->with(['user'])->get();
dd($teachers);
I think you need to update your database structure, you need pk & fk
column separated.

Relation among three tables: proper query and design suggestion

I have three tables (MySQL):
families where I define the products' families
products where I define the products
families_products where I relate families and products
------------------- -------------------- ------------------------
| familyID | code | | productID | code | | familyID | productID |
|----------|------| |-----------|------| |----------|-----------|
| 1 | p | | 1 | p3 | | 1 | 1 |
| 2 | a | | 2 | a5 | | 1 | 3 |
| 3 | e | | 3 | p1 | | 1 | 6 |
------------------- | 4 | e7 | | 2 | 2 |
| 5 | a2 | | 2 | 5 |
| 6 | p4 | | 3 | 4 |
-------------------- ------------------------
I have two questions:
Is this design convenient or is it better drop the families_products table putting the familyID relation directly into the table products?
With a design like this one, if I have the familyID how can I retrieve the products->code? I wrote this query but a query structure like this one would work if I drop the families_products table putting the familyID relation directly into the table products as said before, not in the case of a third relational table.
'SELECT productID, code, img
FROM products AS a
INNER JOIN families_products AS b
ON b.productID=a.productID
WHERE b.familyID=' . $families[$key]["familyID"]
Your data structure is fine.
If you have at most one familyID per product, then you should put the family in the products table. You should use the junction table (your structure) if a product can be part of multiple families.
As for your query, it is fine. I would use better table aliases:
SELECT p.productID, p.code, ??.img
FROM products p INNER JOIN
families_products fp
ON f.productID = fp.productID
WHERE fp.familyID = ' . $families[$key]["familyID"]
If your product only belongs to one product family you can skip the "familiy_product" table and add the familiy_id directly to the product. Only in case a product can be assigned to multipl families you need the "join" table.
With only two tables the SQL is quite easy:
select p.code from family f, product p where f.code ='xx' and p.family_id = f.id

query specific table based on search keyword in mysql

I am creating a search portal in PHP from which user can search for a specific cuisine. In MySQL I have multiple tables for each cuisine and the respective hotel names that offer the cuisine. For example, in table
How can I query a specific cuisine table based on the cuisine search keyword?
So if a user enters 'mexican' as the search query, how can it connect to the 'Table2 - Mexican' and return the hotel names from this table?
Table1 - Chinese
_______________________
| id | hotelname |
|______|______________|
| 1 | hotel1 |
| 2 | hotel2 |
| 3 | hotel3 |
| 4 | hotel4 |
| 5 | hotel5 |
|______|______________|
Table2 - Mexican
_______________________
| id | hotelname |
|______|______________|
| 1 | hotel1 |
| 2 | hotel2 |
| 3 | hotel3 |
| 4 | hotel4 |
| 5 | hotel5 |
|______|______________|
Table3 - Pizza
_______________________
| id | hotelname |
|______|______________|
| 1 | hotel1 |
| 2 | hotel2 |
| 3 | hotel3 |
| 4 | hotel4 |
| 5 | hotel5 |
|______|______________|
Your database concept is very unflexible. I think you should put the cuisines into your database as information (i.e. table content) instead of metadata describing single tables. Tables should generally considered to be static just like the code you write to access the database and its tables. If you implement the cuisines as different tables you would have to hardwire every cuisine into your code.
Here is a suggestion for a better approach:
Create a hotels table to store all the hotels,
Create a cuisines table to store all the different types of cuisines,
Make an additional table to establish the n:m relationship between the hotel and the cuisine.
Example:
hotels: id, name, address, city, telno, email
cuisine: id, name, description
rel: cuisine, hotel (where both are the foreign keys to the
id columns of the respective tables above)
See also:
How to handle a Many-to-Many relationship with PHP and MySQL.
MySQL: Many To Many Relationships ยป Return True
You might want to check this question to create a many-to-many relationship:
many-to-many and many-to-many intersections
I guess what you would like to achieve is something like this:
Table1 - Hotel
_______________________
| id | hotelname |
|______|______________|
| 1 | hotel1 |
| 2 | hotel2 |
| 3 | hotel3 |
| 4 | hotel4 |
| 5 | hotel5 |
|______|______________|
Table2 - Cuisine
____________________________________________
| id | cuisine_name | keywords |
|______|______________|____________________|
| 1 | Chinese | Shandong,Noodles,. |
| 2 | Mexican | Tacos,Beans,... |
| 3 | Itarian | Pizza,Pasta,.. |
|______|______________|____________________|
Table3 - HotelCuisine
___________________________________
| id | hotel_id | cuisine_id |
|______|____________|______________
| 1 | 1 | 2 |
| 2 | 1 | 3 |
| 3 | 2 | 1 |
| 4 | 2 | 2 |
| 5 | 3 | 3 |
|______|____________|_____________|
SQL:
SELECT hotelname, cuisine_name FROM Hotel
INNER JOIN HotelCuisine ON Hotel.id = HotelCuisine.hotel_id
INNER JOIN Cuisine ON Cuisine.id = HotelCuisine.cuisine_id
WHERE keywords like '%pizza%'
Result:
________________________________________
| hotelname | cuisine_name |
|_______________|______________________|
| hotel1 | Itarian |
| hotel3 | Itarian |
|_______________|______________________|
DEMO: http://sqlfiddle.com/#!2/961de/1
Hope this helps
you can check SQL UNION. But instead of having multiple tables with the same fields, you can try normalization to minimize the redundancy and to make queries easier.
Something like:
Hotel Table
-----------------------------
id | hotelname | categoryID
------------------------------
1 | hotel name 1 | 1
2 | hotel name 2 | 2
-----------------------------
Category Table
-------------------
id | categoryname
-------------------
1 | chinese
2 | mexican
------------------
And query as simple as:
SELECT a.hotelname, b,categoryname
FROM hotel_table a
LEFT JOIN category_table b
ON a.categoryID = b.id AND b.categoryname LIKE '%mexican%';

Categories