I have a little issue that has been bothering me, I get the excess of the whole foreign key ideal, owever , could there be any way to get Laravel forign key to a defualt value whenever the reference table is deleted.
One reason I ask this is say for instance say a category is deleted, and the category has alot of say products, when ever the category is deleted the whole product goes along with it.
And then the use has to a new category and then recreate the product that was deleted.
If you want to set null on delete:
$table->...->onDelete('set null');
First make sure you set the foreign key field as nullable:
$table->integer('foreign_id')->unsigned()->nullable();
Related
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.
i have a slight problem here.
i am using stock in the channel with magento, and there plugin uses magento's default tax_class_id.
but the problem we are facing is we have deleted the default magento tax class id.
we have tried to change the plugin to make it use our custom tax_class_id. but as soon we do that plugin dont work.
we have tried to create the same name tax_class but it dont work as it use the new tax_class_id which is now 11.
can we make magento retrieve the deleted tax_class_id?
I don't use Magento, but it sounds like the problem is you deleted a row of data from the tax_class_id table, and when you try to recreate it you get a different value for the auto incrementing primary key tax_class_id, which if I'm correctly reading what you wrote, is confusingly the name of both the table and one of the columns in that table. Not that it matters what they're called, you can go in the tax_class_id table, create a new row, and then double-click on the tax_class_id column to edit the value there to make it match the original value (provided you know what the original value was, of course, but looking in whatever tables reference that value should give you that answer if you don't know). So basically just create it as you've done, it will automatically assign a new counter ID but you can edit that through phpMyAdmin.
Note that, in general, messing with auto incrementing ID values and changing existing data is a good way to mess up your referential integrity, but as long as you have a good backup and understand what you're doing this should work fine for you.
I have a categories table like this for my forum:
CREATE TABLE categories (
category_id TINYINT UNSIGNED NOT NULL AUTO_INCREMENT,
name VARCHAR(60) NOT NULL,
PRIMARY KEY (category_id),
UNIQUE (name)
) ENGINE = MYISAM;
As you can see, I set up the name column as UNIQUE because I intended to allow users to freely create new categories as they wish when they create new posts.
Now, I am creating the edit.php page to enable users to edit their own posts, in which I allow them to change the category of the posts if they wish.
Assume that everything goes smoothly with my UPDATE query for the edit.php page.
However, The problem arised here is that when the user accesses the edit.php page to update the his own post's category, he immediately changes his mind that he does not want to change it anymore. The he clicks the submit button. The error occurs saying Duplicate entry 'x' for key y. I guessed that the root cause was at the unique(name) in the table.
So, should I remove the UNIQUE type for the name column and sacrify the feature of allowing users to create new categories freely?
Or, If I can keep it, your help for a piece of code will be appreciated!
Thanks
This is not a database problem which you can solve with SQL. This is an application problem. If no category must be changed or added, the application should not try to change or add categories. Removing the UNIQUE attribute would probably allow the application to do an unwanted change, which doesn't seem to me a great solution.
Anyway, I suggest you use InnoDB. MyISAM does not provide any benefit for this kind of tables.
Add duplicate validation before update the category this is mandatory
For this case append another condition name != '$_POST["name"]' in the update query.
UPDATE categories SET name = '$_POST["name"]'
WHERE category_id = '$_POST["category_id"]'
AND name != '$_POST["name"]'
Database:
Table: news
With the columns: Unique and Primary Key which auto increments called ID, content and title
Code:
-> Creates a form with a textfield, where the user can put in his value for the ID and thus the position of the item
$form->textField("Position of the item item", "id", false, 30, false, getIfExists("id", $originalValues));
-> Posts the new ID as a query to the database
$queryvalues["id"] = $_POST[ "id" ];
It works when I post an ID that isn't in use by another item. However, if I try to overwrite an ID, it gives me an error and doesn't change anything. Obviously, I'd need to update the IDs, so that it'll increment all the conflicting IDs and thus allowing the edited ID to be posted.
I'm kinda annoyed as how to be doing this. I had the idea of adding an index number that defines the position, then switched to sorting the list with the database ID and changing the ID in the CMS will be able to update that whenever the user of the CMS wishes.
However, I'm not too sure how to approach this and whether there is a better option/solution.
Does anyone have any ideas/tips/hints?
I've tried using ON DUPLICATE KEY UPDATE, but I'm having no luck with it so far.
EDIT:
Alright, so ordering works now. I made a new column called Position and just used that to order the items with and it works fine.
However, if I add a new item, with a same position, it'll put it under the other position. So basically the New "0" gets listed under the old "0", while sharing the same key. Any suggestions on how to fix this? I was thinking of incrementing the old duplicate key. But have no idea how this would work exactly.
Don't touch the id column, leave it as it is. Create a new column called "position" and use that, it will then allow non-unique values.
Your ID is setup to always be unique for a reason and having it auto-increment won't help either. Your id column will inevitably have gaps in it when you delete things but this isn't a problem.
"Primary Key" is forced to be unique and permanently persist. It's an identifier of the Entity and not intend to use as sorting/ordering.
to satisfied your requirement, simply add int or datetime/timestamp field then SELECT * FROM yoour_table ORDER BY field_name
I understand that you want to use the ID to ordering your items : don't do that.
Instead, add a new columns named "ordering" :
When INSERT-ing an item, set this field value to the ID value
When UPDATE-ing the item position, swap the position value between the two items that are moving
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']);