I am working on a basic blog application with Codeigniter 3.1.8 and Bootstrap 4 .
There is a posts and a categories table. At the moment, the application inserts a category id into the posts table , whenever a post is created (you can not add a post before choosing a category for it), but I have set no foreign key relationship between the two tables (for ease of development) and no cascading .
Now I want to set a special cascading relationship between the two tables: whenever a category is deleted, all posts in that category should have 1
in the cat_id
column.
I have created an installation process for the application: after creating a database and providing its credentials to the application/config/database.php
file, you can run the Install
controller which will create all the necessary tables:
class Install extends CI_Controller {
public function __construct()
{
parent::__construct();
}
public function index(){
// Create all the database tables if there are none
// by redirecting to the Migrations controller
$tables = $this->db->list_tables();
if (count($tables) == 0) {
redirect('migrate');
} else {
redirect('/');
}
}
}
The migrations I use to create the posts table are:
public function up(){
$this->dbforge->add_field(array(
'id'=>array(
'type'=>'INT',
'constraint' => 11,
'unsigned' => TRUE,
'auto_increment' => TRUE
),
'author_id'=>array(
'type'=>'INT',
'constraint' => 11,
'unsigned' => TRUE,
),
'cat_id'=>array(
'type'=>'INT',
'constraint' => 11,
'unsigned' => TRUE,
),
'title'=>array(
'type'=>'VARCHAR',
'constraint' => 255,
),
'slug'=>array(
'type'=>'VARCHAR',
'constraint' => 128,
'unique' => TRUE,
),
'description'=>array(
'type'=>'VARCHAR',
'constraint' => 255,
),
'content'=>array(
'type'=>'TEXT',
),
'post_image'=>array(
'type'=>'VARCHAR',
'constraint' => 255,
),
'created_at'=>array(
'type'=>'TIMESTAMP',
),
'updated_at'=>array(
'type'=>'TIMESTAMP',
),
));
$this->dbforge->add_key('id', TRUE);
$this->dbforge->create_table('posts');
$this->db->query('ALTER TABLE `posts` ADD FOREIGN KEY(`cat_id`) REFERENCES 'categories'(`id`) ON DELETE SET cat_id to 1;');
}
What shall I replace the last line with (it has illustrative purposes):
$this->db->query('ALTER TABLE `posts` ADD FOREIGN KEY(`cat_id`) REFERENCES 'categories'(`id`) ON DELETE SET cat_id to 1;');
in order to get the desired result?
UPDATE: my database does use InnoDB .
You need to use
`ALTER TABLE `posts` ADD FOREIGN KEY(`cat_id`) REFERENCES 'categories'(`id`) ON DELETE SET DEFAULT 1`
However, be aware that this does not work with InnoDB. https://dev.mysql.com/doc/refman/5.5/en/innodb-foreign-key-constraints.html
Here is an example using php
function_delete_category($id) {
$this->db->trans_start();
$this->db->where('cat_id', $id);
$ct = $this->db->count_all_results('posts');
if ($ct > 0) {
$this->db->set('cat_id', 1);
$this->db->where('cat_id', $id);
$this->db->update('posts');
}
$this->db->delete('categories', array('id' => $id));
$this->db->trans_complete();
return $this->db->trans_stats();
}
Honestly speaking, you should have the cat_id
column as the foreign key with a soft delete if the category gets deleted.
However, if this is so necessary, you can create a trigger for this, for MySQL to take care of the deletion and updation like below:
Trigger SQL:
delimiter //
create trigger update_post_categories_with_1
before delete on categories for each row
begin
update posts set cat_id = 1 where cat_id = OLD.id;
end//
delimiter ;
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.