How to Safely Change DB Relations in Live Laravel Project?

Laravel Daily
26 Aug 202011:30

Summary

TLDRIn this video, web developer Pavlos Corp demonstrates how to refactor a Laravel project to change a one-to-many relationship to a many-to-many relationship, using a blog example where articles can have multiple categories. The tutorial covers writing automated tests with PHPUnit, migrating data with a pivot table, updating models and views, and ensuring the application functions correctly post-migration. The video serves as a practical guide for developers looking to safely refactor database relationships in existing projects.

Takeaways

  • 🔧 The video discusses a real-life scenario where an existing project's database relationship is changed from one-to-many to many-to-many.
  • 👨‍💻 The presenter, Pavlos Corp, is a web developer with extensive experience in Laravel, offering insights on handling such database changes.
  • 📝 The example project is a blog where each article can be associated with multiple categories, necessitating a pivot table for the many-to-many relationship.
  • 🛠️ Before making changes, it's crucial to write automated tests to ensure that the system's functionality remains intact post-migration.
  • 📚 Automated tests cover various features like viewing articles, editing, and filtering articles by categories, ensuring that the system behaves as expected.
  • 🔄 The migration process involves creating a pivot table, migrating existing data, and then updating the models to reflect the new many-to-many relationship.
  • 🧩 After changing the database schema, the application's views and controllers must be updated to accommodate the new relationship structure.
  • 🔍 The video demonstrates how to use Laravel's Eloquent ORM to manage the many-to-many relationship and update the database schema.
  • 📉 The presenter uses Sourcetree to visually compare the changes in the codebase, highlighting the modifications made to the controllers and views.
  • 🌟 The final step is to run the automated tests again to confirm that all features work correctly after the database and code changes.

Q & A

  • What is the main challenge discussed in the video script?

    -The main challenge discussed is changing a database relationship from one-to-many to many-to-many in an existing, live project, which involves modifying the code, testing thoroughly, and migrating data without introducing bugs.

  • Why is it necessary to write automated tests before making changes to the database relationship?

    -Writing automated tests before making changes ensures that all features work as expected initially. This provides a baseline to compare against after the changes, helping to identify any issues that arise from the refactoring.

  • What is the first step recommended by Pavlos Corp for refactoring the database relationship?

    -The first step recommended by Pavlos Corp is to write automated tests to ensure that all features are working correctly before making any changes to the database relationship.

  • How does the video script illustrate the change from one-to-many to many-to-many relationship?

    -The script uses the example of a blog where each article initially belongs to one category, but the requirement changes to allow articles to belong to multiple categories.

  • What is the role of Laravel in the context of this video script?

    -Laravel is the web development framework used in the example project to demonstrate how to change the database relationship and update the code accordingly.

  • Why is it important to migrate the data before updating the models in Laravel?

    -Migrating the data before updating the models ensures that the existing data is correctly transformed to fit the new many-to-many relationship, which is essential for maintaining data integrity.

  • What is the significance of creating a pivot table in the context of changing the database relationship?

    -Creating a pivot table is significant because it facilitates the many-to-many relationship by providing a junction point between the two related tables, allowing multiple entries for each relationship.

  • How does the video script address the need to update the user interface after changing the database relationship?

    -The script addresses the need to update the user interface by demonstrating changes in views and controllers to reflect the new many-to-many relationship, such as using for-each loops to display multiple categories.

  • What is the purpose of the 'php artisan migrate' command in the context of the video script?

    -The 'php artisan migrate' command is used to apply database changes, such as creating a pivot table and dropping the old category id column, which are necessary steps in transitioning to a many-to-many relationship.

  • How does the video script ensure that the refactoring process is successful?

    -The script ensures the refactoring process is successful by running automated tests before and after the changes, making adjustments to the tests and code as needed, and verifying that all tests pass, indicating that all features are working as expected with the new database relationship.

Outlines

00:00

🛠️ Refactoring a Project from One-to-Many to Many-to-Many

The video script introduces a scenario where a project's database relationship needs to be refactored from one-to-many to many-to-many. The example given is a blog where each article is initially linked to only one category, but the client later requests that articles should be linked to multiple categories. The speaker, Pavlos Corp, a web developer with 15 years of experience, particularly in Laravel, guides viewers through the process of making this change step by step. He emphasizes the importance of testing before making changes, suggesting the creation of automated tests to ensure all features work as expected. The video promises to cover coding changes, data migration, and updating the application to handle the new many-to-many relationship.

05:02

📝 Writing Automated Tests for Database Relationship Changes

This paragraph delves into the specifics of writing automated tests to prepare for the database relationship change. It outlines the creation of feature tests to ensure that the system functions correctly before refactoring. The tests cover various scenarios, such as viewing articles with categories, editing articles, and filtering articles by category on the homepage. The script mentions the use of database factories and seeders to set up test environments, and it provides a detailed look at how to structure these tests in Laravel. The tests are run, and the results are checked to ensure all are passing, marking the first milestone of the project as successful.

10:02

🔄 Migrating Data and Updating Models for Many-to-Many Relationship

The final paragraph describes the process of migrating the data and updating the models to accommodate the many-to-many relationship. It starts with creating a pivot table for the article-category relationship, migrating the existing data to this new table, and then removing the old foreign key column from the articles table. The models are updated to reflect the new relationship, with the 'belongs to' relationship being changed to 'belongs to many'. After these changes, the tests are run again, and as expected, they fail due to the updated database schema. The speaker then discusses the necessary changes in the application's views and controllers to handle the new relationship, ensuring that the system can manage and display multiple categories per article. The video concludes with a demonstration of the updated admin panel and a rerun of the tests to confirm that the migration and code changes have been successful.

Mindmap

Keywords

💡Eloquent

Eloquent is an object-relational mapper (ORM) for Laravel, which provides a convenient, fluent interface to work with your database. It allows developers to interact with the database using an object-oriented syntax. In the video, Eloquent is used to manage the relationship between articles and categories in a blog application, transitioning from a 'one to many' to a 'many to many' relationship.

💡Many-to-Many Relationship

A many-to-many relationship is a type of database relationship where each record in one table can be associated with many records in another table, and vice versa. In the context of the video, this relationship is established between articles and categories in a blog, allowing an article to belong to multiple categories and a category to include multiple articles.

💡Migration

In Laravel, a migration is a PHP script that helps in defining and managing database schema changes. The video discusses creating a pivot table migration to handle the many-to-many relationship between articles and categories, which involves migrating existing data and modifying the database schema.

💡Pivot Table

A pivot table is an associative table used in many-to-many relationships to resolve the many-to-many cardinality. It contains foreign keys that reference the primary keys of the other two tables. In the video, a pivot table named 'article_category' is created to facilitate the many-to-many relationship between articles and categories.

💡Automated Tests

Automated tests are scripts that can be run to verify that a piece of software performs as expected. In the video, the presenter emphasizes the importance of writing automated tests before making structural changes to the code to ensure that the application behaves correctly after refactoring.

💡PHPUnit

PHPUnit is a programmer-oriented testing framework for PHP. It is used for writing and running tests in PHP applications, including Laravel. The video mentions using PHPUnit to write automated tests for the Laravel application to ensure that the changes in the database relationships do not break existing functionality.

💡Factories

In Laravel, factories are a convenient way to generate fake data for testing and seeding the database. The video refers to using factories, such as the 'ArticleFactory', to create test data for articles and categories, which is essential for testing the many-to-many relationship.

💡Seeders

Seeders in Laravel are used to populate the database with test data. They are typically used in conjunction with factories. The video mentions the need for seeders to prepare the database with the necessary data for testing the application's functionality after refactoring.

💡Refactoring

Refactoring is the process of restructuring existing computer code without changing its external behavior. In the video, refactoring involves changing the database relationships and updating the code to accommodate a many-to-many relationship between articles and categories.

💡Admin Panel

An admin panel is a back-end user interface that allows administrators to manage content and configurations. In the video, the admin panel is part of the Laravel application where articles and categories are managed. The refactoring process requires changes to the admin panel to handle the new many-to-many relationship.

💡Feature Test

A feature test in Laravel is a type of automated test that checks if a specific feature of the application works as expected. The video discusses writing feature tests to ensure that the application's functionality, such as viewing and editing articles with categories, remains intact after the refactoring.

Highlights

The video demonstrates changing a one-to-many relationship to a many-to-many in an existing project.

The example project is a blog where each article can have multiple categories.

The presenter, Pavlos Corp, is a web developer with 15 years of experience, focusing on Laravel.

The project includes an admin panel and a home page displaying articles and categories.

The process starts with writing automated tests to ensure features work as expected before making changes.

Automated tests cover admin viewing articles, editing, adding articles, and home page functionality.

The importance of having green tests before refactoring is emphasized to minimize risks.

The video shows how to create a pivot table for the many-to-many relationship.

Data migration is demonstrated with a single SQL query within a Laravel migration.

The article model's relationship is updated from 'belongsTo' to 'belongsToMany'.

After updating the model, tests are run to identify failures that need to be addressed.

Changes in the views and controllers are shown through GitHub history for visual comparison.

The admin panel's category selection is updated to support multiple selections.

The home page and article page are updated to display multiple categories per article.

The video concludes with all tests passing, indicating a successful migration.

Additional resources for learning about testing and Laravel's many-to-many relationships are provided.

Transcripts

play00:00

have you ever worked on a project where

play00:02

you had to change a relationship from

play00:04

one to many to many to many

play00:06

in existing project which is already

play00:08

alive so how to change the code how to

play00:10

test everything how to make sure there

play00:12

are no bugs

play00:13

how to migrate the data all of those

play00:15

questions will be answered in a demo

play00:17

project in this video and we will do

play00:19

exactly that

play00:20

step by step on an example project so

play00:22

imagine there is a blog

play00:24

and every article on a blog has one

play00:26

category and at some point client

play00:28

changes their mind and want the article

play00:30

to have many categories possibly

play00:32

so let's do that change step by step

play00:35

before we dive in if you are new to this

play00:37

channel or you don't know me personally

play00:38

my name is pavlos corp i'm a web

play00:40

developer with 15 years of experience

play00:42

five of them in laravel and i've created

play00:44

laravel business youtube channel to

play00:46

share my knowledge about laravel

play00:48

so with 400 videos it's a pretty big

play00:51

library of videos so i advise you to

play00:53

subscribe now let's get back to the

play00:54

video

play00:55

so imagine you have a blog with articles

play00:57

and in the code in eloquent you have

play00:59

article model

play01:00

with category belongs to relationship

play01:02

and in the database

play01:04

you have articles table with category id

play01:06

field and

play01:07

in your website you have two parts admin

play01:09

panel which is

play01:10

generated with our quick admin panel and

play01:12

also you have list of articles some kind

play01:14

of home page with

play01:15

all articles category list list of

play01:18

articles by category and page of

play01:20

certain article this is a quick demo

play01:22

project created by my colleague marios

play01:24

with some dummy data but it's

play01:26

a real life scenario and imagine we need

play01:28

to change the article to be

play01:30

multi-category and it needs to be

play01:32

changed everywhere

play01:33

so in this case you have to query

play01:35

articles in a different way

play01:36

when viewing the articles the category

play01:38

list should be a for each loop not just

play01:41

one category

play01:42

then in admin panel when adding new

play01:44

article you should

play01:45

change how category is selected it

play01:48

should be multi-select

play01:50

also in the list of categories there

play01:52

should be not one category but also

play01:54

for each loop probably so quite a lot of

play01:56

things to change

play01:57

where do we start and how to make it

play01:59

safely and let's start from a different

play02:02

question

play02:02

how will you test everything after you

play02:05

make the changes in the code

play02:06

and to answer that question there's one

play02:08

rule of thumb my own personally

play02:11

how to make any big refactorings in any

play02:13

structure of a big project

play02:15

is first you need to write automated

play02:17

tests so you need to write

play02:19

tests of all the features how they

play02:21

should work

play02:22

so you wouldn't need to test that

play02:24

manually everywhere because manually you

play02:27

will totally forget something

play02:28

so let's write a script and let's hire

play02:31

robots to do that job

play02:33

so in our case let's write automated

play02:35

tests for if i'm an admin i see articles

play02:37

with categories i can edit article i can

play02:39

add

play02:40

article then from the home page i see

play02:42

the articles with right categories

play02:44

the articles are filtered in the right

play02:46

way and stuff like that

play02:47

so like a dozen of tests for every

play02:50

feature for every scenario which would

play02:52

cover how

play02:53

system works currently before doing any

play02:55

changes for relationships so step one

play02:58

is to write automated tests ensure that

play03:00

those tests are green

play03:02

and successful then we make the change

play03:04

for the relationship and everything in

play03:06

the code

play03:07

and by that time those automated tests

play03:09

should fail

play03:10

and then we need to change those tests

play03:12

to represent a new reality

play03:14

so if in the test the article is created

play03:16

with belongs to relationship

play03:18

it should be created what belongs to

play03:19

many now but the scenario in the test

play03:22

should be the same so we expect to see

play03:24

the list of articles

play03:25

and then when the updated tests are

play03:27

green and successful

play03:29

we are pretty sure that we did okay job

play03:31

at least it minimizes the risks

play03:33

so in this project we did exactly that

play03:36

step by step i won't do it live code

play03:38

because it would take a lot of time i

play03:39

will show you the result

play03:41

and first milestone is automated tests

play03:43

even if you have no

play03:44

tests in that project it's worthy to

play03:47

write them specifically for this case

play03:50

for this scenario you're refactoring

play03:52

and even if you haven't written

play03:53

automated tests before

play03:55

i have a few things to help you there is

play03:57

one video about simple demo for php unit

play04:00

and also i have a separate course for

play04:01

php unit in laravel for beginners

play04:04

so let's look into the code we've

play04:05

created tests feature category test

play04:08

and let's see how it works so it

play04:10

refreshes the database every time

play04:12

because we will launch

play04:13

test on a separate fresh new database

play04:16

specifically for testing

play04:17

and then there is a method setup test so

play04:19

what we need to prepare for

play04:21

all the cases launch the default heaters

play04:24

create three categories as an example

play04:26

create 10 articles

play04:28

for example and then assign some default

play04:30

variables which we will use inside of

play04:32

those tests

play04:33

for that we need to have seeders we need

play04:35

to have factories so

play04:37

we create a database factories article

play04:40

factory for example with faker

play04:42

and then we can launch the test for

play04:44

example for the case of

play04:45

let's close that one test if admin can

play04:48

view the articles with categories

play04:50

and the code of the test is simple we're

play04:52

acting as

play04:53

this user and this user is the first

play04:56

user of our system which is

play04:57

administrator

play04:59

we're getting the url of articles and we

play05:01

assert that the status is okay 200

play05:04

and we assert that we see the article id

play05:07

the article title the category and the

play05:09

word view which is a button to view

play05:12

so in the admin panel here we see the

play05:14

title we see the category we see the

play05:16

button view

play05:17

it's called the feature test so we're

play05:18

testing if feature works okay

play05:21

we don't really care how it works under

play05:23

the hood we just see the correct text

play05:25

and then test by test we check other

play05:27

things so

play05:28

new article safe category we are saving

play05:31

the category and then we assert if the

play05:33

database has the correct article with

play05:35

correct category

play05:36

then test for editing the article

play05:39

for updating the article and then a few

play05:42

tests on the home page

play05:43

so homepage show categories so outside

play05:46

i'm not logged in as administrator

play05:48

anymore

play05:49

we're getting the articles and check if

play05:51

there is an article

play05:52

in the list with category and with read

play05:55

more link

play05:55

then we check articles by category so if

play05:58

there is a url with category id

play06:00

we check that all the articles are

play06:02

present so correctly filtered by that

play06:05

category

play06:06

finally test article page show we assert

play06:08

see that the category is present

play06:10

and if we run those tests in phpstorm

play06:13

inside of that

play06:14

we passed eight tests with 15 assertions

play06:17

everything is okay

play06:18

so this is the first milestone

play06:20

successful green

play06:21

test before any changes of the code next

play06:24

step

play06:24

is actually change the data so first we

play06:27

need to create a pivot table with

play06:29

article category

play06:30

then we need to migrate the data and in

play06:32

our case it's just

play06:34

one statement inside of migration one

play06:36

sql query so inserting into article

play06:38

categories

play06:39

select everything from articles and at

play06:41

this point our data is migrated and then

play06:44

third thing we need to do is to drop

play06:46

that column of category id

play06:48

this is an example that inside of one

play06:50

migration in laravel you can do whatever

play06:53

sequence of actions you need

play06:55

you can change the data you can change

play06:57

schema in multiple ways

play06:59

in one migration and if we run that

play07:01

migration in the terminal so php artisan

play07:03

migrate

play07:05

it is successful and if we look in the

play07:07

database refresh the tables

play07:09

there is article category filled in and

play07:12

articles table doesn't have category id

play07:15

anymore

play07:16

so we change the database now we need to

play07:18

change the models

play07:19

so in article php we changed category to

play07:22

categories belongs to many

play07:24

so it was belongs to now it belongs to

play07:26

many and

play07:27

category head has many articles now it

play07:30

belongs to many articles

play07:32

and at this point we should run the

play07:34

tests again and see if they fail they

play07:36

should actually fail

play07:37

we run the tests so seven

play07:41

tests failed which means that we

play07:42

actually broke the system at this point

play07:45

and now let's fix it again so let's

play07:46

change our views and controllers

play07:49

to reflect the new relationships now

play07:51

changes in the code in the controllers

play07:53

and views i will show you that as github

play07:55

history

play07:56

because it's much more visual you will

play07:58

understand before and after

play08:00

i will use a software called sourcetree

play08:02

for that

play08:03

and let's see how much it is changed so

play08:04

everywhere we have article category you

play08:07

need to change that into categories both

play08:08

in admin panel

play08:10

so storing the article is not just store

play08:12

we need to sync the categories with that

play08:15

and quite a lot of small changes so

play08:17

categories sync here in admin panel

play08:19

then we generate api as well in quick

play08:22

admin panels so that needs to change as

play08:24

well

play08:25

then in request form requests we need to

play08:28

validate the categories as well in a

play08:30

different way

play08:31

then article factory when creating the

play08:33

article instead of doing category id we

play08:35

need to

play08:36

create the category so assign the

play08:38

categories as well

play08:40

then forms for administrator quite a lot

play08:42

of html and

play08:44

changes for multiple for each instead of

play08:47

just

play08:47

simple select drop down so create edit

play08:51

then index blade is also changing so

play08:53

instead of showing category name

play08:54

we're showing for each of the categories

play08:56

and then when it's shown

play08:58

also free so that's admin panel and then

play09:01

on the home page

play09:02

article controller changing the

play09:04

relationship and changing the query

play09:06

if it's with category id as a parameter

play09:09

and

play09:09

in the blade we also in index we change

play09:12

the categories

play09:13

how it is shown and in the show we also

play09:15

show multiple categories

play09:17

so quite a lot of changes like dozen or

play09:19

two of files

play09:21

and if we check out that commit

play09:24

the project should be working so we can

play09:27

launch the home page again

play09:28

and we can see multiple categories for

play09:31

article

play09:32

it's actually only one in this case so

play09:34

let's assign multiple categories to for

play09:36

example article

play09:37

with id50 and by the way you see the

play09:39

changes in admin panel as well

play09:44

so let's assign multiple categories

play09:47

and article id 50. let's change that to

play09:51

url with id 50 and let's see if it works

play09:54

well

play09:55

so comma separated two categories but

play09:57

now how do we make sure

play09:58

we actually didn't miss anything and

play10:00

it's all working

play10:02

let's get back to our tests if we run

play10:04

the tests again

play10:05

now tests failed too and we need to make

play10:08

some changes to the tests

play10:10

so if we go back to our source tree

play10:12

inside of the test we set up the

play10:14

situations

play10:15

with some data which we need to change

play10:17

so instead of acting

play10:19

with category id as a parameter to post

play10:21

we need to post the categories as

play10:23

array then we need to assert the

play10:26

database has in a different way

play10:28

so a few more changes to the tests

play10:31

and our next goal is to make them green

play10:34

again

play10:34

and i've applied those changes and if we

play10:36

run the tests again

play10:38

finally it's all green and at this point

play10:41

we're pretty sure that our migration is

play10:43

successful

play10:44

we check the database if the data is

play10:46

okay

play10:47

we checked visually if it's clickable

play10:50

and everything is

play10:50

kind of loading and at the back of all

play10:53

of that we wrote and run automated tests

play10:56

that make sure that all the features are

play10:58

still working and to be honest those

play11:00

tests

play11:00

could be even deeper so with more cases

play11:04

but it's at least basic minimum of

play11:06

common main features to test

play11:08

if you want to learn more about testing

play11:10

as i said there is a video and

play11:12

my own course so i will link them in the

play11:14

description below

play11:15

and if you want to know more about pivot

play11:17

table and many-to-many relationships

play11:19

there's one popular video on this

play11:21

channel and i will link that in the top

play11:22

left corner so you can take a look

play11:25

everything i know with details about

play11:26

pivot tables in laravel

play11:28

and see you guys in other videos

Rate This

5.0 / 5 (0 votes)

Étiquettes Connexes
LaravelRefactoringMany-to-ManyAutomated TestingDatabase MigrationWeb DevelopmentEloquent ORMPivot TableTesting StrategyCode Change
Besoin d'un résumé en anglais ?