Now we will go a bit deeper… So… By referring to what we did in the previous tutorial (a table named “users” that has “id”, “username”, “email”, and “password” as fields), we will try to see how we can alter the table the way we want to.

Let’s pretend that we want to add another column to the table: “name”. Don’t jump to the idea that we should open the migration file we’ve written in the previous tutorial. We won’t. That’s the idea with the “git” part in our title. We want to have a history of our changes. If we would have modified what we’ve just created where would the history be?

So we will create another migration file, let’s name it “add_name_field_to_users_table”. Remember the “timestamp” we’ve talked about in the previous tutorial? We need to append that to our file name. Also, make sure that the “timestamp” represents a date and time that are after the timestamp of the migration file that creates the table, as the migrations are made in the order of the timestamps. So let’s create a file named “20150724111200_add_name_field_to_users_table.php” (wow… that’s a loong name, isn’t it?… if you find a better name that will help you understand what is done in the migration file, go ahead an name it the way you want).

Now let’s see what we can write in there. We start with the same template:

PHP

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

<?php

defined('BASEPATH')ORexit('No direct script access allowed');

classMigration_Add_name_field_to_users_tableextendsCI_Migration{

publicfunction__construct()

{

parent::__construct();

$this->load->dbforge();

}

publicfunctionup()

{

}

publicfunctiondown()

{

}

}

On the up() method we mention the fields we want to create in a $fields array:

PHP

1

2

3

4

5

6

$fields=array(

'name'=>array(

'type'=>'VARCHAR',

'constraint'=>100

)

);

Now we only have to call the dbforge in order to alter the table:

PHP

1

$this->dbforge->add_column('users',$fields);

And that’s it. But wait, why don’t we put the column just after the “username” column and not at the end?

We can do this by changing the $fields array and adding a key named “after” with the name of the column as value:

PHP

1

2

3

4

5

6

7

$fields=array(

'name'=>array(

'type'=>'VARCHAR',

'constraint'=>100,

'after'=>'username'

)

);

Take note that “after” and “before” work only with a My_SQL database.

Now that we’ve finished with the up() method, we move on to the down() method. We only have to ask the dbforge class to remove the column:

PHP

1

$this->dbforge->drop_column('users','name');

Now let’s look at the migration file again:

PHP

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

<?php

defined('BASEPATH')ORexit('No direct script access allowed');

classMigration_Add_name_field_to_users_tableextendsCI_Migration{

publicfunction__construct()

{

parent::__construct();

$this->load->dbforge();

}

publicfunctionup()

{

$fields=array(

'name'=>array(

'type'=>'VARCHAR',

'constraint'=>100,

'after'=>'username'

)

);

$this->dbforge->add_column('users',$fields);

}

publicfunctiondown()

{

$this->dbforge->drop_column('users','name');

}

}

Cool, now just go to the controller method do_migration of the Migrate controller (assuming you’ve created it with me in the previous tutorial…), and the new column should have been created if everything went ok.

But… Oups…

We just remembered that we don’t want to do a “name” column, but two columns: “first_name” and “last_name”. So why not rename the “name” column to “first_name” and add the “last_name” column?

We create a file named: 20150724122000_rename_name_field_add_last_name_in_users_table.php (this is like the contest for the longest file names…)

To change the definition of the columns we simply call the modify_column() method of the dbforge class, and pass it the table name and the columns we want to change. To create the new definitions we must use an array that has as keys the name of the columns and an array as the value with the new definitions. So, our array would look like this:

PHP

1

2

3

4

5

$fields=array(

'name'=>array(

'name'=>'first_name'

);

);

PHP

1

$this->dbforge->modify_column('users',$fields);

OK… sorry for the fact that the column name is “name”… That will turn a lot of heads…

I hope you’ve got the taste of migrations. But, as practice makes perfect, it’s time to use what you’ve learned. So go ahead and try using the migrations. I can’t stress it enough, DO READ THE FINE MANUAL on the CodeIgniter site: