Laravel 6.x relation set default value on delete on relationship partner - php

I have the following two models:
stockItem. category
stockItem can have one category and category can have many stockItem.
Incategory there is alway the first category with the id of 1. It can not be deleted.
Now if category with id of 2 gets deleted, all stockItem with the relation to the second category should be updated to the first category.
Is ORM capable of that or do I need to write an own delete function? If so how do I overwrite the delete function?

There is a way to go for this but you must make some modifications.
Laravel has onDelete actions when running migrations. For your problem i think suitable is:
->onDelete('set null');
In order to have this work you will have to change your foreign key (categoryId) to be nullable.
Having done that when you delete a category then all the relations that this category had will be set their field to null, meaning they will belong to category1 which can never be deleted.
This is the approach to do it with pure migrations and this is the closest you can get. That way you will know that when categoryId is null or 1 this stockitem belongs to category1 or was transferred to it cause another category was deleted.
If you really need the id to be 1 then you should use either a helper class that you build yourself, or Laravel Observers.

Related

Laravel 4.2 ORM - Querying relation with various tables in between

I have a database schema that goes like this:
Section
id
name
Subsection
id
name
section_id
Category
id
name
subsection_id
SubCategory
id
name
category_id
Product
id
name
subcategory_id
As you can see, each table has a foreign key that references the previous table. The problem comes when I try to get, for example, the Section from the current product or get all products from one section. So far I have tried this:
Section::with('product')->find(1)->product;
But I get this:
SQLSTATE[42S22]: Column not found: 1054 Unknown column
'product.section_id' in 'where clause' (SQL: select *
from products where products.section_id in
(1))
1 - This makes me think I need to set up a section_id in the products table to make this work. Is this correct?
2 - Shouldn't the Laravel ORM automatically go up the table hierarchy from Product to Section and get the results?
3 - Is there a way to do this maintaining my current table structure, I mean, without adding extra fields in the tables for the foreign keys?
Thanks.
No that is one way to do it but it isn't the only way.
No, how would it know that automatically?
I believe so and you can always create a specific query when laravel relationships don't work for you.
Okay first this assumes you have relationships setup on all the models to access the one below it. If that isn't the case you will need to setup the relationships.
Section::with('subsection.category.subcategory.product')->get();
I've never tried such extreme nesting but I believe this will work. The Laravel Docs talk about eager loading and scroll to see the nested example.
Another item that comes to mind is the hasManyThrough relationship. You couldn't do it for this number deep but it may be something you want to look into.
A brief summary from the docs is taking the first three from your example, Section, Subsection, and Category and then in the section class you would have this relationship.
public function category()
{
return $this->hasManyThrough('Category', 'SubSection');
}
The laravel docs with more information.

Best approach for Doctrine2 with productdata sharded per category

I'm using Doctrine2 in a Symfony2 project and I've to build against an already existing MySQL database with productdata. There are about 40 productcategories and millions of products. Each category has it's own table in MySQL, all with the same schema.
Simplified:
Every table also has its own primary key ID field, so it's possible to have several products with the same ID, but coming from a different category.
All references to these products are now by category ID + product ID. The current software selects the data from the correct table based based on a defined mapping between the category ID and the MySQL table. This mapping is made in a seperate categories MySQL table, and rarely changes.
I've looked at inheritance mapping in Doctrine2 and it seems the best solution would be to make a mapped superclass. After that I can make 40 subclasses that extend this superclass, for each category one. I would still need some kind of mapping between the category ID and the correct subclass entity.
Is there a better approach to this? Because with this solution I would have to find the correct subclass entity based on the category ID.

Resolving many to many relationship MYSQL database

I have 3 tables,
users(id) , userproduct (user_id,product_id) and product (id).
When a user adds a product their user_id and the product_id is saved in USERPRODUCT table.
Now at the same time another user can save a product (kind of like "set as favorite") for this I need to save the user_id of the user who saved it and the product_id of the product. This will create another table (call it favorites) however this table is also a resolve to the many to many relationship between "users" table and "product" table.
the question: is it possible for this, to have 2 tables resolving a many to many relationship or is there any other way to solve my issue.
if it is possible how will one be draw this in the ER diagram
it depends on what you want.
you may use only one table and design your relations with boolean fields
USERS(id)
PRODUCTS(id)
USERPROD(userid, productid, isbought, isfavorite, isowned)
or you may use one many-to-many support table for every relation is up to you
maybe you want another field "owner" in PRODUCTS table to store the user id. this is a one-to-one relation
What you want to do is actually describe the kind of relation between user and product: a favorite, or he 'owns' it.
Just add another field to the userproduct-table defining the relation: favorite or owned

How do I make doctrine do not try to update a table?

I'm working on a project where we use views to create a interface/layer between another system which is a datasource but have no matching model. This way, in my system, these views are in fact models. Everything is working perfectly fine until now, except for this part:
-------------------------------
|Table |Table |View |
-------------------------------
|Order > |OrderItem > |Item |
-------------------------------
Relation: Order (has many)> OrderItem (has many)> Item.
I recently faced a problem where it tries to save the entire set of relations of a table (the order). The system is supposed to save the order and its items (order-items). But somehow the save ends up hiting an update on the item model which is a view and returns this error, obviously:
Code:
$order->save();
Error:
Data manipulation operation not legal on this view : UPDATE ITEM (...)
Is there a way to track this, forcing it to not occur, or set it as a read only model?
This error occurs in mysql when the view is composed of elements from different tables.
If you edit columns from the same table it's ok but if the same query tries to edit columns for different tables you have an ERROR.
Are you still using Doctrine 1.2?
I think using views with Doctrine was tricky Link
ALso the error can come from the way you declared the relationship on the entities:
Having:
Order Many-to-Many OrderItem Many-to-One Item.
You should make sure take the relationship OrderItem > Item is unidirectional and that OrderItem is the Owning side.

MYSQL modeling relationships: Design and UPDATE/DELETE

I am trying to understand relationships fully, and have gone through alot of tutorials. Still i linger on a few things (using MySQLWORKBENCH):
1. Every user can upload a product
2. Every product can have multiple categories, bids, ratings, etc
3. Every user can have multiple phonenumbers
(there are more, but this is the basic setup)
Is this correct?:
1 - I used a 1:n relationship, since every user can upload multiple products.
2 and 3. I used n:m relationship, since there can be multiple products with multiple categories, bids, ratings, etc.
DELETE/UPDATE:
I used ON UPDATE CASCADE and ON DELETE CASCADE everywhere where there is a foreign key...that being 'product', 'category_tags_has_products', 'bid_price_has_product', 'phone_has_user'.
I tried to delete a product like this (php): mysql_query("DELETE FROM product WHERE id='$id'");
I get a 1054 error, which is a foreign key error.
What are the best practises here? It is to my understanding that i shouldn't need to do deletions in any other than the parent-table?
Thanx!
You have a lot of identifying relationships, which mean that the foreign key form part of the primary key on the second table. This is not necessary in most instances, and is only really useful in instances such as link tables.
To this end I would change the user->product link to be non-identifying, which will make user_id a Foreign Key instead of being part of the Primary Key. In workbench the shortcut for a 1:n non-identifying relationship is key '2' (where as '4' is identifying). This in turn should remove the user_id fields from the tables which product links onto.
When you delete a product, it should cascade to the 3 link tables that it links to. At present it may be that it is trying to delete from users also depending on how the FK is set up. The following should cascade deletions (assuming a deletion is permanent and you just want to clear out all linked records)
DELETE FROM product -> deletes from any table with product_id in
DELETE FROM user -> deletes from any table with user_id in
The same applies for phone, rating, bid_price, category_tags.
I hope this if of use, if you need any further pointers feel free to shout :)
The relations look correct.
To find out what is wrong with your query check the $id variable.
Or check the whole query and then run it in the console/phpMyAdmin/etc:
$query = "DELETE FROM product WHERE id='$id'";
var_dump($query);
mysql_query($query);
P.S.: and don't forget to escape all data got from the users! Like this:
$id = mysql_real_escape_string($_GET['id']);

Categories