I have a invoice model which can belong to a product or a plan ... my database looks like this
invoices : id , type (enum:product,plan) , price
invoice_products : invoice_id , product_id
invoice_plans : invoice_id , plan_id
plans : id , title
products : id , title
when I want to show my invoices for the purchased item I have to write something like
$purachse = $invoice->invoice_plan->plan ;
Or
$purachse = $invoice->invoice_product->product ;
Is there a way to get rid of invoice_product in my relation?
I want to get the product or plan but I don't want to keep going through invoice_product I prefer laravel to handle that for me.
something like belongsToMany but for 1-1 relation .. there is hasOneThrough but it wont work as I thought.
You have to use Laravel polymorphic relations: https://laravel.com/docs/9.x/eloquent-relationships#one-to-one-polymorphic-relations
Related
Using Laravel, I'd like to fetch an order status (order_status table) from an order (orders table) based on the
locale relationship stored in the orders table using a pivot table (order_status_locale table).
The pivot table contains the "localised" order status from the order.
Of course, I could fetch the localised order status (order_status_locale) directly from the database, but I'd like to
fetch the localised order status through a Laravel relationship.
Something like this:
$order = Order::find(123);
$order->localisedOrderStatus->label;
This is an example of the database structure:
orders:
id: int
locale_id: int
...other columns
locales:
id: int
...other columns
order_statuses:
id: int
...other columns
order_status_locale:
order_status_id: int
locale_id: int
label: varchar
its sometimes better to make model of your pivot table. like OrderStatusLocale.php
then you can make the relation through it.
lastly if you want to achieve
$order->localisedOrderStatus->label;
you can use laravel has one through. or i think its better to go through the relation like $order->order_status->locale->label
Database schema
I have these three main tables:
products
groups
users
And these two pivot table:
product_user
group_user
Each user has a group.
Each product has a price which may be overriden by a price in the product_user pivot table or by a price in the group_user table.
Problem
Now I know how to join these tables and everything but with my current solution I am only able to select each of these prices to a separate column like price, user_price and group_price and prioritize them using PHP.
Question
Is it possible to select these 3 columns from these different tables and prioritize them into one column using only Sql?
So if there is a user-specific price selected this price into price, if not and there is a group-specific price selected this one and if there is no special price select the products default price.
Laravel specific solution
As #Shadow pointed out below, the solution is the MySQL coalesce function.
Using Laravel's query builder I was now able to achieve what I want using this statement:
$query->addSelect(
DB::raw('coalesce(product_user.price, group_product.price, products.price) as price')
);
Use the coalesce() function to return the 1st non-null value from its parameters.
select coalesce(product_user.price, group_user.price, product.price) as price
from ...
Since you have not shared the exact schema with me, I cannot provide mpre specific help. I assume that there are price columns in the tables.
In my database I have one table that contains a complete list of products, and another table that contains the same list of products on the x-axis, with a list of customers on the y-axis, where the value for each product can be 1 or 0 depending on whether that customer can view that product. My SQL looks like this:
SELECT products.product_code, products.product_type, products.product_category, products.product_title, products.product_description
FROM product_lists
INNER JOIN products
ON product_lists.product_code=products.product_code
WHERE product_lists.customer="1"
ORDER BY products.product_code
My problem is that I would like to create a view of this result for each customer to use as that customers product table, however when I create it I get the message "This table does not contain a unique column. Grid edit, checkbox, Edit, Copy and Delete features are not available." even though the product_code field is set as a primary key in both the products table and the product_lists table.
How can I create a join/view that uses the primary key from the table(s) it was created from? In short I would like the product_code field to become the primary key of my view.
Thanks!
I think the problem is the join. You can fix this by moving the condition to the where clause. MySQL doesn't allow subqueries in the from, but it does in the where:
SELECT p.product_code, p.product_type, p.product_category, p.product_title, p.product_description
FROM products p
WHERE EXISTS (SELECT 1
FROM product_lists pl
WHERE pl.product_code = p.product_code AND
pl.customer = 1
)
ORDER BY p.product_code;
What is the best practice to do a searching form with filters, where the filters are depending on the category?
e.g.:If you go to visit the ebay and select a category then the filters are different on the left hand side in the cell phones (filters: brand, operating system...) or the fashion category (filters: size, color...)...
In my mind I would do more table in DB. Each table for one category (cat_cellphone, cat_fashion...). Then put a product one of these tables depending on the category (not one products table where one column contains the category ID).
These tables are different where the columns names are characterized by the category.
Next, should do more searching forms and call a form where the filter belongs to the category.
Is it a good concept or there is an other accepted practice in big projects?
No, having multiple tables is a bad idea.
In general. use a table with a primary key over two columns instead.
(The primary key may span more than one column.)
The columns would be categoryname / filtername.
If you don't like such primary keys, and always use an autoincrement column, you can still create an index over the two columns.
The columns would be: id / categoryname / filtername / filtertext
Using multiple tables to store your products isn't a good idea. Because there will be products that overlap in categories which would result storing the same product in more than one table.
Just use a product table with the ID, product_number, description, etc. and a category table to store the different categories. Then you could link them directly like:
Product table:
ID product_number description category
1 00001 Screwdriver 1
Category table:
ID description
1 Tools
And you could even expand the category table with an extra column to use subcategories by addressing the parent of the subcategory:
Category table with subcategories:
ID description parent
1 Tools NULL
2 Automatic tools 1
And if you don't like directly linking to the category table from the product table you could use a link table:
Product_category:
Product_ID Category_ID
1 1
Hope this answers your question.
Edit, added filter table:
To add filtering for a product you can use a table for a the filters and a link table, like so:
Filter:
Filter_ID description value
1 brand Bosch
2 brand Bahco
3 type Phillips
Product_Filter:
Product_ID Filter_ID
1 1
1 3
That way you can link more than one filter to each product and use the same filter more than once.
You could even expand this further by using another table for the filter values, but that could make things a bit to complicated:
Filter:
Filter_ID description value
1 brand 1
Filter_value:
Filter_ID value
1 Bosch
2 Bahco
I am trying to create a link table in mySQL to manage the association of products and skus. An example, the product is a t-shirt. The sku is each t-shirt's size and color combination. I want to handle products and skus many-to-many relationships because we sell items and bulk. Bulk products may be comprised of individual skus. Ergo, one sku could be associated with many products.
So, I am pretty sure I need products and skus to have a many-to-many relationship. What I don't understand though is how to poulate the Link table. In other words, when I create a product I generate a productid in the product table. When I create the sku I have a skuid in the sku table. How to I take the productid and skuid (each primary keys in the thier own table) and add them to the link table. Each skuID and productID pair should be unique so I would like those two fields to serve as my primary key.
Anyway, when I try to create the relationship in phpmyadmin using the designer I get "Error: relation not added".
so basically you are trying to link 2 tables 1 for t-shirt product and 2 thsirt size and color, for table 1 make a product id which is primary and for table 2 create a product id field similar to table 1 which will link your two tables the only difference is that in table 2 product id is not your primary key