TDD Laravel - Lets Build Personal Budget Website | Arturo Rojas | Skillshare

Playback Speed


  • 0.5x
  • 1x (Normal)
  • 1.25x
  • 1.5x
  • 2x

TDD Laravel - Lets Build Personal Budget Website

teacher avatar Arturo Rojas

Watch this class and thousands more

Get unlimited access to every class
Taught by industry leaders & working professionals
Topics include illustration, design, photography, and more

Watch this class and thousands more

Get unlimited access to every class
Taught by industry leaders & working professionals
Topics include illustration, design, photography, and more

Lessons in This Class

25 Lessons (4h 43m)
    • 1. 1 Intro

      1:01
    • 2. 2 Setting Up Aliases and New Project

      4:27
    • 3. 3 It Can Display All Transactions

      14:25
    • 4. 4 Transactions View

      6:40
    • 5. 5 Transaction Categories

      4:40
    • 6. 6 It Can Filter By Category

      7:14
    • 7. 7 Test Helpers

      4:38
    • 8. 8 It Can Create Transactions

      9:26
    • 9. 9 Input Validation

      13:53
    • 10. 10 It Only Allows Authenticated Users

      18:51
    • 11. 11 Create Transactions View

      22:04
    • 12. 12 UI Enhancements

      3:30
    • 13. 13 It Can Update Transactions

      9:57
    • 14. 14 Edit Transactions View

      16:27
    • 15. 15 It Can Delete Transactions

      9:52
    • 16. 16 Filter Transactions by Category & Month

      19:53
    • 17. 17 It Can Display All Categories

      9:54
    • 18. 18 It Can Create Categories

      10:14
    • 19. 19 Create Categories View

      11:07
    • 20. 20 Update Categories View

      11:26
    • 21. 21 Routes Refactor

      20:51
    • 22. 22 It Can Display Budgets

      22:25
    • 23. 23 It Can Create Budgets

      8:49
    • 24. 24 Create and Update Budgets View

      13:25
    • 25. 25 Query Optimization

      8:16
  • --
  • Beginner level
  • Intermediate level
  • Advanced level
  • All levels

Community Generated

The level is determined by a majority opinion of students who have reviewed this class. The teacher's recommendation is shown until at least 5 student responses are collected.

113

Students

--

Projects

About This Class

The toughest part of learning Test Driven Development is where to begin. Here, you get a quick jumpstart by creating an entire project using TDD & Laravel 

Develop faster and deliver better products

By using Test Driven Development, you will not only discover how much it improves your development speed, but also how much more confident you are about your final product, knowing that it has been thoroughly tested and it works as intended.

Meet Your Teacher

Teacher Profile Image

Arturo Rojas

Teacher

Class Ratings

Expectations Met?
    Exceeded!
  • 0%
  • Yes
  • 0%
  • Somewhat
  • 0%
  • Not really
  • 0%
Reviews Archive

In October 2018, we updated our review system to improve the way we collect feedback. Below are the reviews written before that update.

Why Join Skillshare?

Take award-winning Skillshare Original Classes

Each class has short lessons, hands-on projects

Your membership supports Skillshare teachers

Learn From Anywhere

Take classes on the go with the Skillshare app. Stream or download to watch on the plane, the subway, or wherever you learn best.

Transcripts

1. 1 Intro : the purpose of the scores is to give you a good practical example of a real live application created from scratch using test driven development. Our project will be a small personal budget application where we can keep track of expenses . But before we start coding, let's go over our project requirements. First of all, we should be able to see our monley budgets. We should also be able to see all of the transactions we made for a given month. We will need the ability to create, update and delete budgets as well as transactions in categories and finally, the project. We require authentication, but little Bill will take care of that. I will assume that you already have a working development environment with little homestead installed. If you don't just go over level documentation and follow the instructions to install Homestead in the next video, we're going to take care or setting up our new project and creating our first test 2. 2 Setting Up Aliases and New Project: So let's start by setting up our environment. The one thing they want to do first is to set up some. Adidas is for my most commonly used commands. For example, I'm going to use heavily BHP unit. So I don't want to have to write this BHP unit every single time, so I'm going to instead created 90 is called Team. Also, I will frequently filter my test by running only one test at a time. And to do that, usually you have to do BHP unit Dash dash filter equals in the name of the method, but this is very long. So I want to shorten that. And instead I want to simply type TF and then the name of the method. I'm currently inside Homestead, but I'm going to log out using the excitement and inside the homes. That folder there should be a file called Alice is if we inspect this file using them, it already has a bunch of aliases created for you, provided by a lot of it, like this alias for the See the home command by simply typing H or analogous for the clear command by simply typing. See, down here I already added my alias for PHP unit by simply typing cool. And for the future, I simply area start as a function using T, which is the alias for BHP Unit, adding dashed ach filter equals and using the dollar at sign you can passing a parameter to this alias function. So whatever you type after TF will be placed here where it says dollar at sign. So I'm going to close this file and look back into homes it So, Like I said, every time you see me typing T, what I'm actually typing is PHP unit. And every time I type TF and then some test method what I'm actually typing this PHP unit just as fielder equals some testament, it is worth noting that if you are going to add your own analysis to the aliases file outside Homestead, you have to re provision. You're bitter machine, and you can do that by typing vagrant reload de stash provision. You do that inside a homestead folder. This looking back to homestead in the next thing we want to do is to create a new fresh lateral project, and I'm going to do that inside a coat folder within Homestead, which is my shared folder between the little machine and the operating system. You could use a lot of a new to create new level projects, but I prefer to use Composer so I will take composer, create a lot of ill forward slash level and let's call this Project budget. And for this project, we're going to use level version 5.4. This process is going to take some time, so I'm going to briefly pause the video and come back when it starts. But right, the process is done, and now you have a fresh project, and we have to do is CD into budget up and whatever comes with PHP unit out of the works without any configuration. So right away you can start testing because it also includes a couple of examples test cases that you can use as a reference. So if you recalled, I created an audience for PHP unit Instead of that, I can just simply type team and he enter to run all of the test in the project. And as you can see, we have a green coat and it executed two tests with a total of two assertions. So now we can start creating our own tests. But before that, let's go back to the project requirements and decide what are we going to test first? I always recommend that you start with the simplest says that you can do so that you can warm up and start creating code right away and from experience. I can tell you that this plane information screen is one of the simplest is that you can execute. I don't want to start testing the view monthly budget because that will interact with transactions. Instead, let's start by creating a simple test that will demonstrate that we can display all of the transactions in the screen. Now that we have decided where to start in an expedient, we're going to create our first test. 3. 3 It Can Display All Transactions: in the last video we created our basic project in Lauraville and now I haven't opened in. My editor is pretty much a simple lot of a project. Fresh start. Nothing new about it. But now it's time to create our first test in like we discussed before. We're going to start with showing all of the transactions in a simple view and to create the test. We're going to go to the Terra meaner and to create our first as this will be a feature test. We simply type Ph B. Artisan. Make this and let's call this new test view. They're in sections test, and now we go back to the editor in Little Created a new file for us within the tests feature folder called Beauty and Sections Dist. And let's start writing our first test. There are two ways to name your test cases. One is to prefix the method name with the word test or another one. This is the one I prefer, and I will be using throughout the course is by simply using at test before the method name as a decorator and simply name my method whatever I want, and I usually like to call it that something like it can and then the rest of the description in this case, it can display all transactions. And to begin with, I would like to have a record of a transactional database so that I can displaying in the screen. And I'm going to use model factories to accomplish this. So I will say transaction equals two fact duty. And here we passed. The name of the class in this case will be AP transaction. This will be our model class and then called create. And this will create a new instance of our model class and then persistent to the innovates with the information we provided to the model factory. Then what we want to do is to visit the page where we want to display all of the transactions and then assert that I can see this transaction in the screen. To do this, we simply tied this get and this would represent a get method to a girl. In this case, I went to name it simply transactions. And now I simply assert seeing and I am looking for the transaction. Let's say the transaction has a description, and that's all there is to it now, this is expected to fail. But with every error, we're going to add code that will clear that error until we have cleared all the errors and then achieve a green status. So I'm going to filter by this method name and then go to the terminal. And like I mentioned in the last video, I'm going to use an alias called TF and then the name of the method and that will execute BHP Unit and filter by only that method. And now we get our first error saying that we are unable to locate factory with name default app transaction. And this has to do with the fact that we don't have the model factory yet for the transaction model. And if we want a model factory first we need to create the model. So we tie PHP artisan. And in fact, if you are within Homestead, you can just type artisan and then say make model transaction. Now let's go back to the editor and let's take a look at that model and this is just a basic model. Now we need to create a model factory for it and to do that. We need to open a file located in database factories, and it's called Model Factory. In here, we can see that there is already one mortal factory defined for the user moral class. So let's use days as a reference. Just copy it and paste it below, and we will need one for the transaction. Mother, we don't need a password in this case. And let's say that for now, I only want my transactions to have a description. Let's use faker sentence and let's make these a two word sentence. The field name is actually description. Now that we have a mortar factory in place, let's go back to a terminal and test again. Now it's telling me that the table homestead transactions doesn't exist, and this is because of two things. One, we haven't configured anything on the database side, and two, we have no to find any migrations yet for a project. So let's go ahead and solve the first problem. I don't want to use the default homes that schema, so I'm going to quickly create a new schema for my budget application within Homestead. You can do this by typing my SQL minus you for the user and the user will be homestead and then minus p for password hit, enter and the passport will be secret. Now here will simply create a new database with create database in Let's call it budget db on a semicolon at the end and he entered. And there you have it. We have a new data is created. Now I exit out of my SQL and then switch back to the editor to go to the Arab is configuration. In this file, the database configuration file is located inside conflict database. I'm going to scroll down to the end to the connections array, and here you can see that he's spooling a lot of data from thes environment variables. So let's modify those. And those are located in the dot e N v file. So let's open the thought in Avi file, which is in the root folder of your project and for the database name. We're going to use budget DB. The user name will remain the same, and the password it stays the same. So with this modifications, let's see if the error from the test has changed. Run the test again and yes, you can see we are no longer use in the home city for schemer. Now we are in our own schema, but we still don't have any transaction stable. So let's solve this problem by creating a migration file for the stable again. Since we are with Homestead, I can simply type artisan make migration. I'm going to call it, create Trinh Sections table and then, at the end with at dash dash, create equals. And then the name of the table transactions was Go back to the editor in this open immigration file called Create to in Section Stable. And by the way, this file is located within the database folder and you should see a Migrations folder in there and that that's where all the migrations are created and you can see the new one here a little bit already. Scaffold at some of the most commonly used columns for us in the up method that creates a table, and then the down method, which drops the table. I'm going to leave this to as they are, and then at a new one called Table String. Agnes called this description and this will be my description color. Okay, Let's go back and test again to see if we got rid of the current error, that we have run the test again and we still have the same error. But this is because we haven't told the test case to execute any migrations. To do that, we go back to the editor that we need to include the database migration, trade into her class. Let's see if that fixes the problem back to the terminal and execute the test again. And as suspected, it is failing. But the problem here is that it's spitting a bunch of HTML in at the end, complaining that none of it contains the transaction description. But we can't really tell what the error is. So instead of trying to figure out all of these HTML and trying to parse out what the error is, let's fix this right away. We are going to fix this for a class by disabling exception handling to show you how this looks like in a browser and show you exactly what the error is. This quickly configure our website for this project by Xing It out off the West or machine in this quickly added a file called homestead dot Yemen. This is the configuration file for Homestead to our new website. Simply look for the sights section, and it's at a new line here to map au aerial for application. Let's call it budget that a PP and let's map that to our project, which will be inside home vagrant code budget up And finally we have to map this toothy public folder. Now we simply saved the file and repre vision Arbiter machine using vagrant reload Prohibition. This will shut down the veritable machine and re provisioning with the new configuration. Finally, we have to edit r e t c host file by doing them forward slash it see forward slash hosts and in some cases this will be ah, protected file. So you may want to use pseudo vim instead. Now we have to add a new line with the I P address that is configured for Homestead in this case 19 to 168 the 10 that 10 and then the u N. For application, which is budget that a PP save the file in exit. Now let's go back to homestead. Use in vagrant Is this h back into a Project folder. Let's run that last test again just to see the ever one more time. Now let's up in the browser, in this case, chrome a navigate to budget up transactions. As you can see, we have a not found http exception, which has to do with the fact that we don't have any routes yet but laterally scratching that exception. And instead of throwing it, he's displaying this HTML page to us. But in testing that is not going to work. So the general idea is that we want to bypass laterals, exception handling and throw the exception. Instead of displaying this HTML page for this purpose, I have created a quick code snippet in Get Hope that I will share with you and the resources section of the scores, and we're going to use this piece of code to modify the based test case in level. So I'm going to switch to row, select everything here, switch to my editor and open based test that PHP and that is located in the Tests folder. If I this called desk case that BHP so like everything and replace it with the code that we just copied and to give you a quick run down off what we just modified. We simply introduced a set up method for every single test in which we execute a parent set of method and then called the disabled exception handling method. And this method simply overrides the default exception handler from level. It replaces that with this new passed through handler class, and this class simply is a replica off the fold exception handler from lateral. Except that we are not implementing anything except the render method and this render matter, all it us is re throwing the exception to the screen. Now if we want to re enable exception handling, we simply called the with exception handling method. And all that is doing is simply reinstating the old exception handler that we had before. With this in place. Let's go back to the terminal and we run our test to see if this works. We execute the same test again, but this time I expect to see the exception and not the HTML, and sure enough, it fails. But this time we have a clean exception not found http exception as before, which has to do with the fact that we still don't have any routes, so let's go and fix that. Let's open routes web dot PHP And here we will add a new get route pointing to transactions , and this will be handled by the transactions controller on the index method. Let's go back to the terminal in test again. Now it's telling me that the transactions comptroller does it exist. We can create this quickly by saying, Artisan make controller. They're in sections, control it and hit Enter just one more time to see a different error. Now it's telling me that the method index doesn't exist, so let's go back to the editor. Open the transactions controller in at a public method called Index. Let's go back to terminal and test again. Now it's failing to assert that the transaction description is visible and this is the point where I wanted to get. We're going to make a pause here and in the next video we're going to create a view for the transactions least 4. 4 Transactions View: to get started on the views. I'm going to let Ladder will do all of the scaffolding for me. So in the terminal type artisan make out, this will create a new layout file we can use for the new view. Let's move on to the editor and open the resources The use folder here. I'm going to create a new folder called In Sections and inside It I'm going to create a new PHP file called index dot blade dot PHP. In here. I'm going to extend from layouts, Uh, which is the layout filed. A lot of it created for us when we scaffold in the authentication system. In fact, let me show you real quick. Let's jump into grown. And if we navigate to our application in budget that a PP, we can see a couple of new links up top called logging and register. And if you click on either of those, you have the authentication system that we scaffold and all of these works out of the books . By the way, here you can logging into the system. Remember your password if you forget it, and if you go into the register section, you can create new users. The layout file includes the heather up top and also the finds the background color for the entire application. But let's go back to the editor and, more specifically to orb you file. And let's start with a deep class container, which will give us some margins on the sites. Next, let's add a new DIF class stable, responsive so that our table will scroll horizontally on small devices. Next, let's at a table class stable with a table heather and table body. It's at a new row for the heather and here we're going to display the date. The description in the transaction amount now for the table body. I'm going to reiterate over the transactions using a for each look and for each transaction , I'm going to display a row here. I will display the date so I will see you in Section created at and in verse in 5.4 level, will transform dates into carbon instances so we can give it a nice format like this. Next let display did section description in finally different section amount. Let's return to the terminal and run the test again. It is still failing to assert that the transaction description is being shown the screen, but this is because we still haven't returned any view from the controller. So let's go back to the ater off pen The transactions control it again. And let's return a view called 10 sections dot index back to the terminal. It just one more time. And now we're getting an error saying undefined, bearable transactions. And yes, it's fairly overuse that we were going to get that a road, and we could easily have added that variable before, run the test and wasted a couple of seconds. And if you think that you're totally right, just remember that there are no rules. Carbon stone me. Personally, I like to get the errors from the test so that I can go and fix those one by one. But you could totally go in at two or three extra lines of code to get ahead of the next error in dentist. Just make sure you don't go too far ahead. Otherwise, if you find a book, you're going to have to backtrack. Just find it, which can be time consuming. But anyway, let's go back to the editor and send that transaction viable into our view. Let's define a new transactions variable, and this will be quote, too. Transaction. All I remember to import these section class, and here we are a second parameter in C compact, different sections. Let's go back to Terminal Test again and it passes Perfect. Now there is one thing I would like to correct right away. As of now, we are working with the life database, which means that every time we run a test, Lauraville is going to execute all of the migrations, create the tables at the records and then roll back all of the migrations, effectively deleting all of the tables in our database. Now, I don't want to keep doing this in a light that are based. Instead, I want to do this in an in memory databases specifically for testing. For these, let's go back to the editor and let's open a file called PHP unit dot XML, which is located at the root of your Project folder. At the bottom, we have some environment variables already defined like, for example, the application environment with the value of testing gas driver, he said. Toe array as well. A secession river in the queue. Draper. Let's copy this one and at another value right below it in this college DB connection and give it a value off sq a light. We're going to use an SQL light in memory database for our testing copy and paste this one again right below it and this one. Let's call it D B database and give it a value Colin memory color, and that's it. If we go back to the terminal and run the test again, we should get the same results. But this time we're not running against alive, that of its we're running against on in memory SQL database. And sure enough, we get a green status in the next video. We're going to add a category to each transaction. 5. 5 Transaction Categories: let's add a category to our transactions. In this case, I simply want to add another assertion right below this one to say a certain see and let's say something like Transaction Got a goatee name. Now I am expecting these to fail because I don't have any categories yet, but I am going to let the test let me know that so I can go ahead and fix it. So I'm going to copy this method name moved to the terminal test in filter by that method only, And I get on error exception trying to get a property off a non object. And this is because I am trying to access the name on a category which is going to return. No, because it doesn't exist now. This category. It's supposed to be a relationship between the transaction model in a category mother, so let's start by creating that model. First, let's move to a terminal and say artisan, make mother dignity. Now let's go back to the editor and open deed transaction model. And at a public method called category in here, I'm going to return. This belongs to category class, and that should be enough. Let's go back to the terminal and test again. Now it's telling me that the category stable doesn't exist. So we need a migration for that. And right here in the terminal, we can create one by saying, Artisan, make migration, create category stable and to scaffold some of the code I add The create option equals categories, which will be my table name. Okay, now we have immigration. Let's go to the editor again and open that migration. And we know that at least we should have a string column called Name. So let's at that one with table string name back to the terminal and test again. And now we're back to the previous exception trying to get a property of a non object. But this time is because we still don't have any model factories for the category mother. So back to the editor. Let's open the mother factory file. I'm going to copy the definition for the transaction model factory and simply replace the class with category. And the only column that we have is the name. So let's make that a one word sentence, which should be pretty much word now whenever I create a transaction I would like that transaction to belong to a category. To do that, I would like to populate the category I D column with a newly created category. To do that, I simply assigned these two and anonymous function, which will return factory up, get dignity, create. And once that is created, I will return the nearly created category I D. Let's go back to Terminal in test again. You know, we get a new ever saying that the transaction stable doesn't have a category I d. Color. To fix this, let's go back to the editor and opened the create stir in section stable. Endless are a new column In this case will be an unsigned interview called Category I D. Back to the Terminal and let's see if we get rid of that ever. Just again. And now it's complaining because The Rendered view doesn't contain the category name, and luckily, this is very easy to fix. Let's go back to the editor in less Open Transactions Index that played that PHP. Let's add the new heather right after description, the school, this dignity and then you column and here we say section got integrity. Nay, back to the terminal in just one more thing. India. We got agree code in our test s passing, and that should be all for now. In the next video, I'm going to add a new test to make sure that I can feel they're all of my transactions by category. 6. 6 It Can Filter By Category: So in this video I want to be able to feel terror. My transactions by category blister with a new test. And let's call it it can filter transactions by category. First, I'm going to need a new category to be specific. So category equals factory at category create. Next, I'm going to need to transactions one with the category I d. That I just created in another one with another category. So Lester with transaction equals factory up there in section create. And here I went to the specific about the category i D. And it's signed that to the newly created category I d. Next I need another section. Let's just call it for their conception and that will be equals two Factory Captain section . And remember that if we do not specify a category i d. The model factory will create one for us. Next, I want to be see the transactions Lee Space age using the transactions your l and first of all, I want to assert that I can see the transaction description and I don't want to see the older transaction description and to actually filter the transactions, I would like to be able to pass a parameter to the U R L. And it will be nice effected. You say transactions food or something like abilities or something, like maybe Transportacion anyway, something that is descriptive and it's easy to understand. So that tells me that I need something like a slug in my category. So let's pretend that exist. And just append that to the Ural, using contiguity slow. So again, this doesn't X East just yet. But I'm going to let the test let me know so that I can add the necessary code. Okay, I think this is enough so we can go ahead and test. Let's copy the method. Name again has moved to the terminal test and filter. Bye, Dad. Method name and see what we get. Okay, so it is complaining because it's failing toe assert that the renter view does not contain the transaction description, which means that it's not filtering the transactions to fix days. Let's go to the editor and open the routes web that Ph. B. And I am going to use this same route. But I am going toe append a new parameter called cut dignity, and I'm going to make it option and meaning that if I don't pass it, he's not going to need it, and it is not going to cause any errors. Now let's open the transactions controller. And here I'm going to use implicit model binding. So all I have to do is type in the category class, and it's called this category and default that to know. And here I would like to filter by the category if one is provided. So let's say if category exists, then I say three sections equals two did in section where Category 80 equals two category I d. Otherwise we moved this lying from here to here in that will effectively give me all of the transactions. And if you're thinking well, this is starting to look a little bit too complicated, you're probably right. And that is an indication that this is probably something I would like to re factor in the next iteration. But for now, while I'm interested, used to make the test pass. Once I get a green coat, I will go back to this goat and clean it up. Let's go back to the terminal in test again, and we still have the same error as before, so it's still not filtering. And the reason for this is that implicit model binding assumes that you are passing a numeric value that is representing the key or the I D in the category stable. But instead of that, we are passing the categories luck. So how do we tell Lauraville that we want to filter our categories? Not by the i d. But by this lock? Well, that it's actually pretty simple. Let's open the category model in at a public function called Get Route Key name. And here we simply return this stream. It's look, which represents the name of the column that we want to filter by when we are using implicit model binding. So let's see if this solves the problem. Let's go back to the terminal in test again. And no, we're still having the same problem. But this is because we still don't have any slug column in our table. So let's go back to the editor and opened the migration file. Create transaction stable known, actually create category stable. Let's at another text column. So string slug. And now we want to populate Thesis column in the model factory so up in the modern factory . And I'm going to take this and put it in a viable over here. Call it name in a sign that here and the reason I do this is because I want to use that name as its look, so slug. And here I'm going to use a little helper method. Cold str slug and pass it the name and what this method does is it takes the string passed in s parameter and converts it into a U L friendly slot. Let's go back to the terminal in testicle and we're still having the same error. That is interesting. Let's review this HTML real quick, and this should be the body of the table and is not actually throwing anything into the view. Let's go back to the editor to see what I mean is in the controller open deterrence sections. Control it. And let's see, uh, of course, it is going into this condition, but at the end, I forgot to add the get method which will actually go and fetch all the records for me. Let's go back to terminal to see if that fixes the error. Just went with time and now we get a green excellent, and that will be all for this lesson in the next video, we're going to take some time to create some tests helpers that will make our lives easier going forward. 7. 7 Test Helpers: in this lesson, We're going to create a few tests helpers that are going to help us save some time. Now, this is a personal recommendation, and you can choose not to follow it if you want to, but it release a time saver. Have you noticed that we have been using this factory function a lot? And just by this couple of test cases, I have already used, like four times, and it's a little bit of a long line. So how about if instead of this long line, we had a helper method called create and simply called that in past the class name is a parameter just like this. To do this, let's start by creating a new file. You can create this while anywhere you want, but for orders sake, I'm going to create it inside the Tests folder. Here, I'm going to create a new directory or folder called Utilities, and inside that folder I'm going to create a new PHP file called Test Helpers. Here I'm going to create a function called Create. It will receive the class name as a parameter and also an array of attributes that we want to overwrite unlisted folk that to an empty every. Oh, and also let's add another parameter for the number of times I want to create this glass. Doesn't fault is to know, and other days does is simply return factory repairs the class name the number of times create in past the attributes. Now we need a way to make this create function globally accessible to our project. To do this list, open the composer that Jason fell and right below this PS are four. Section this at a new section called Files, and this will receive an array of files that we went to out a load in this case is just one entry, which is tests utilities, test helpers that PHP. Now all of we have to do now is switched to the terminal and run composer Dump out alone, and this will refresh the outer load files for composer, and that's it. Now let's go back to PHP real quick back to our view transaction test, and I'm going to undo these changes just to make sure that we are getting a green status first. So I go back to the terminal, run all of my tests and make sure I get a green status and seems I screwed up Something related to the filtering by category transactions by category. Let's go back to the editor to see what happens, and it can feel transactions by category were sending Theo Seems like a remove. The G k that's fixed little back to the terminal, just everything again and okay, we are getting a green stuff, so it's time to go and modify the test and make sure we get a green status. When we're done, go back to the editor and I'm going to start removing this factory create and simply called create. Select several them replaced with create and remove this here these array of attributes from here I'm gonna pass it ASAP within to create function this one and finally removed this one. Now with that finished, let's go back to the terminal, Run everything again, all of the test again to make sure that I didn't break anything and we're still getting a green status. That is great. Now, finally, let's go back to the editor because I know that in the model factory file I'm still using the old factory creates. So I want to fix that too. So open more than factory instead of calling factory, Create Mr School create remove this create method Here the i d states the same and that's pretty much it. Let's go back to the terminal, test everything again. Make sure that we are still getting a green status and we do Perfect. That was a good re factor and artists are looking better. This is a way simpler line of code that is going to help us a lot in the future. And that is all I want to show you for this video. In the next video, I will add the ability to create new transactions. 8. 8 It Can Create Transactions: before we start working on creating the transactions, there are a few things that I'd like to fix in thes ah method in the transactions controller. And I'd rather do it now than later now that I have a green status on the test. First of all, I failed to explain something in the last lesson. When we make whenever we make a parameter optional in the route. And let me assure you this by opening the where the PHP file the routes web, that BHP far when we had this to a perimeter in a you Ariel, that means that we're making it option. Er, if we use implicit model binding, then we don't need to. Actually default is to know because this will never be no. What happens here is that if we do not provide any parameter, flattery will simply give us an empty instance of a category class. And when that happens, the exist field will always be force. Because this is a fresh model and has not been persistent to the database yet is actually empty so we can remove that default to no from the method. The next thing I want to fix is this long. If here, actually there is a better way to do this. It'll be nice if we can remove this logic from here and simply have something like category transactions equals two transaction by category. And here we can simply pass the integrity as a parameter and then call the death message to the So my intention is to replace all of this logic from here and simply at one line of code that will do exactly that to accomplish days. I'm going to add a local school to the transaction model. So let's open the section model and down here, let's at a public function called scope by category. And the way this works is whenever you prefix a public function with the word scope, everything next to it will become the method that we can use to call this function. If you notice if I call by category over here, I am actually calling this function scope by category. Now, this method will receive the query, which will be a reference to the query builder for the model, and we can add more parameters to it. For example, we can type he and the category that we want to filter by. That's called this category and writing here. We can say if cut their body exists, then we can apply and you filter to the query Where category I d equals category. I d. All right. With that in place, let's go back to the controller. Then let's remove this logic firm here. Just remove those lines all together. Let's go to the terminal and test everything again to make sure everything is working still , and we still have a green status. That means that the reflector that reaches state was successful, and just by taking a look at it, we reduce all of those lines into choose one single line. That is easy to understand, all right, And with that finish, let's move on to create transactions. First of all, I will create a new file within feature and you PHP file cold, create transactions, test in. Let's define a new test class called Create Transaction Test. Extending the based test case using batteries, migrations and the first test will be it can create transactions, and the first thing I need is a fresh set of data to boast to a certain you are ill. So that it will create any transaction for me. This means I need to create a nutrient section using factory AP transaction. And instead of calling create, we simply call them make function. This will create an instance to the transaction model without persisting into the database . But we're really created a helper message for the create Minted. So why don't we create another helper method for make so that I can simply call make after in section like this? So let's open the test helpers that pH being going to copy this function call it make the parameters will be the same. But instead of calling, create Aiko, make go back to the test. Now that I have a neutral section, all they have to do is post to, let's say, transactions. We passing the data, which will be the Transaction two array because the post method will accept an array of data and we have to transform a model class into a flat array of data. Now, what I expect is that whenever I do a post to the transactions Eurail, it should redirect me back to the transaction least so assert, redirect to the in sections and also If I visit the transactions page using get transactions, I should be able to see the transaction description. And I think this will be enough to start testing. So let's copy the method name and missing a letter here to array. Okay. In Skopje, the Method name. Jump into the Terra meaner test infielder by that Onley and hit Enter. Let's see what errors do we get? We get a method not allowed exception. This is because we are missing the route so back to the editor. Let's create in your l by opening routes web dot PHP and down here. Let's at a new post route for transactions and this should be handled by transactions controller and the method will be the store method. Okay, back to terminal and test again. We get a different area if we screw up old with up. It says that the Method store doesn't exist, so let's go ahead and that that back to the editor, open the transactions controller in regular the index method list another public function or public method called store. With that in place, jump back to terminal in test again. Now it's telling me that response status co 200 is not a redirect Status Co. If you remember from the test, were first asserting that once we posed to this year L we are expected to be redirected. Do these transactions your L, which is the least of all transactions. But the method is actually returning empty, so the coat status will be 200. To fix this, let's go back to the sections controller in this return. A redirect to transactions. And now let's go back to the tear Amina Intestine. And now it's complaining because the render view does not contain the transaction description to fix days. Let's go back to the editor to the transactions controller in here. We're going to create a new transaction using current section create. This will receive an array of data that we're going to get from the request. We can do that by saying request, and for now, let's just bring all of the request. So requests all. Let's jump back to the terminal and test again. Looks like we have another error insane mass assignment exception specifically for the description, and this is because we're using mass assignment in our controller by saying that in section create but we haven't defined which feels at a mass sustainable in the transaction model. To do that, let's open the transaction model and right up top can be here. Let's define a public field gold fallible. And here you can include out of the column names that you want to be mass. Assign nable or if you don't want any fields to be guarded, simply say public guard equals empty arrays. And with that were basically saying all of the fields for these model are not guard. Personally, I don't like this approach because it leaves the model to wide open, so I'm going to use the other one fallible in past description, which is a column name. This is, in fact, to the terminal just again, and we have another error, and now it's complaining at that of its level, because the category I D cannot be no in this again, it's because of mass assignment. Go back to the editor, make sure that the Category 80 isthmus sustainable but terminal in test again, and now we get a green coat. Great, expressing. Let's this everything. Just make sure we didn't break anything in the process and we're still getting a green status. All right, so that'll be your for this video. In the next lesson, I'm going to take care off. Input, validation. 9. 9 Input Validation: Right now, we know we can create transactions. But what happens if we try to send invalid data to the transactions using the post? Let's try it out and see what happens. Let's say, for example, when we make Eastern section, let's make the description. No. If we try to test this again, let's go back terminal latest and feel terrible. This method only we get an exception saying integrity, constraint, violation not no constraint. Failed transactions. Description. This basically means that the description of the transaction cannot be no at a data base level. So obviously we don't want this to be caught at a data base level. We want Ladder Ville to validate data first. And if something is missing, report the errors back to the U I so that we can show them to the user. So let's create a test that will make sure that the data has to be valid In order for us to create a transaction. Let's go back to the editor and down here, let's create a new test in this college. It cannot create transactions without a description. First of all, I'm going to steal this line of code from here copy and paste down here. And let's remove these description Equal snow from here. And I'm going to copy this other line from here, copy and then paste it here and here I am doing another post to transactions. But this time, the transaction that I made it's incomplete with their description equals to know. And now I would like to assert session has errors, and I am explicitly looking for a nearer in the description field. So here I am asserting that after I make a post to the transaction, you are really with an incomplete in section specifically without description. I want an error flash to the station containing the description key. Okay, Lets copy the method name moved to the terminal test and filter by that method only. And if we scroll up, basically we get this same exception as before. But this is expected because we are not performing any valuations. You see it? So to do this, let's go back to the editor and opened the transactions controller and inside the store method right before we create a new transaction, we can say this validate the request. And on the second parameter, we passed the array off rules. Toby Validate. In this case, I want the Description field to be required in. As I said before, when this validation fails, Larible is going to look on error, indecision and then redirect back to the previous page. The error locked in the session will contain valuation errors for any of the fields that failed to pass a validation from this array. In this case, we only have one, which is the description at this point. So with this in place, let's go back to the terminal in test one more time. And it seems like we still have a nearer Let's grow up and see what's the validation of and looks like we still have an error scroll all the way to the top, and it's actually throwing a validation exception. And this is because one important reason we modify the based test case to disable exception handling. But in this particular case, we don't want the exception to be thrown out into the screen. But we actually want lateral toe handle the exception itself, which means that we have to re enable exception handling. So let's go back to the test and right before we make post this called enable or actually, with exception handling. Let's go back to the tear Amina in just one more time and now it passes and we get a green status scope. Excellent. We are now validating to import. Next stuff will be to make sure that we cannot create transactions without a category. So I'm going to make another test. In this case, let's call it it cannot create that in sections without a category, and the process will be very similar to this. So I can just copy and paste this whole piece of code from here based it down here and now , instead of setting the description to know, let's say category I d. It's equal to know. And now I am looking for an error on the category. I'd color and I have a typo here that's better. Okay, lets test is one now to see if it still works. Copy the method name. Look to the terminal test and filter by this method only, and we get an error saying session is missing expected key errors, which means that we are doing validation. But we are not evaluating the category I d. So to fix that. All we have to do is go back to the letter, open the transactions controller again in at another field to this array. It's a category idea, and I want this to be required as well. Let's go back to the Tear Amina Intestine and it passes. Excellent. Now we're validating the description in the Category 80. At this point, I'd like to introduce a new piece of data into the transaction, and that is the amount of the transaction. Say, for example, the description of the transaction was lunch, and I want to say that that lunch cost me 17 bucks or something like that. Then that will be the amount 17. So I have to add another column to the transaction to store the amount. So to do this, let's go back to the editor. First of all, let's open the migration file for Deterrent Section Stable, which is called Create Transaction stable in regular description. That's a table. This will be a float column, Endless, called this amount. Now, by just making this'll change. I am expecting some of the test to fail, but let's go and execute all of my tests to see what are the repercussions up, just adding one column, which is not knowable to my transaction state. And this is the beauty of testing, because this change, as small as it may seem, has a potential off affecting your application in many different places. So let's jump back to the terminal and less test everything to see what fails. Let's scroll all the way to the top, and here we can see that we have three Evers and the first error was found in the IT Cane Creator and sections test, saying that the amount cannot be no. So it's failing at a data base level. So let's start by fixing these errors first, and then we can move on to any of the other errors. So, first of all, I'm going to copy the method name from here in test and filter by that one only so that I can isolate it. And again, it's failing at a data base level with an integrity constraint violation in the Amount column. To fix this list, jump to the editor. Let's go back to the test and look for the it can create transactions test. So the problem here is that we are making a transaction, but the model factory is not populating the amount. So let's open the model factory in right after the description. Let's feel the amount column and let's set that to a random number. Actually, let's make that a number between five in 10 just to make it simple. Okay, with that change, let's go back to the terminal and see if that fixed it test again. And we still haven't error and is the same error as before. So this time it's because the model itself it's still not showing that the Amount column. It's my sustainable. So let's go back to the editor, open the transaction model and let's add another. Enter here for the amount. The order is not important, so it doesn't matter if you put it here or at the end, as long as it is in theory in that should fix it. So let's go back to the terminal intestine it Okay, we fixed one error. Let's see if we still have any other errors in our application by testing everything again , and it looks like by just fixing the first error, we fixed all of them, so that's great. We have a green status with all of our tests passing. But now I want to introduce validation for the amount. So let's go back to the editor, Open the test again. And down here, let's at another test. And let's call it it cannot create sections without an amount. No, I don't know if you notice, but I'm starting to see a pattern here because the easiest way will be to just copy and paste this code again. Basic here, change category I d for Mt. And change that here as well. But we're starting to see a lot of code repetition. So instead, why don't we move all of this logic to its own method? I'm going to create a public function down here, and I'm going to call it both student section. And here I'm going to receive an array of attributes or over writes for the new transaction , the fault in Theis to an empty arrange. And I'm going to bring all of this copied this'll lines of code from here to here in this second line, I'm going to return this. Actually, I'm going to use this overwrites array instead of this. And now, instead of this two lines of code, I can simply say this post transaction and pass an array off overwrites in this case will be the amount set to know, and this will give me the return of post in on that return. I can simply assert the decision has errors regarding the M L. I'm going to do the same for this other tests here. In this case, it's the category D In same goes for the description base that let here and say description , and with that simple reflector in my tests are looking a lot better in their easier to read . Now let's focus for a moment on the amount. First, copy the method name, jump back to the terminal test and filter by this method only. Obviously it fails because we are not validating the amount yet, So let's go back to the letter. Open the transactions controller minutes at one more entry for the amount and it is require . Let's go back to the terminal end test. And yes, we get green status so that when it's passing now, let's make sure I didn't break anything with the fact that I did by testing everything again and we still get a green status in everything is passing. Excellent. Now there is one last validation I want to make, and that is that the amount has to be a number. So let's go back to the editor and let's create a separate test for this validation. So here, let's create a new test case. Let's call it eat cannot create 10 sections without a badly amount, and this is very similar to this test here. So I'm going to copy the previous test basic here. And let's set the amount to something other than a number, maybe ABC, for example. And that should be enough. Let's copy the method name, jump back to the terminal test and filter by this method only, and it fails, obviously, because we're not validating that yet. So back to the editor, open the controller, the transactions controller. And here I'm going to add to validation rules to the same clear. To do this, I simply use the pipe character and as well as being required. I need this to be a numeric field, and that should be enough. Let's go back to the terminal test again, and I should get a green status now, and that's correct. We have a green status, justice, everything. And yet we still got win. Everything is passing excellent as of now, technically, you can access the transaction least without being locked into the system. We need to fix this to allow only authenticated users to access the transaction list. Also, users should only be able to see their own transactions in not transactions created by other users. So we're going to take care of these two problems in the next video. 10. 10 It Only Allows Authenticated Users: so far, we are able to see all of the transactions created in the system. Even if we're not signed in, let's restrict this area to authenticated users only. Let's add a new test in view transactions, this class, and we can add it up here. And let's call it it allows Onley authenticated users in here. I will simply visit the transactions page using a get to They're in sections in. Since I am not logged in, I inspected to be redirected to the logging page. Let's go ahead and test this one. Only Skopje, the Method name jumped into the terminal. Destined filter in Hit Enter. It fails because response status code 200 is not a redirect status coat. And that is expected because we are not restricting access yet. Let's jump back to the editor, open the controller and inside the transactions. Control it. Let's at a constructor and inside. We're going to protect this entire controller with a authentication middle where, and we can achieve these by calling these meet aware both. Let's go back to the tear Amina in test again, and we have one. A road that see that, of course you see that it is throwing the unauthenticated exception back at us, and that's because we disabled exception handling in a past video. So let's jump back to the editor, and in this case, we need to enable exception handling. We can do that by using the with exception handling method. All right, let's just again back to the terminal. You know, we get a green coat, but what happens if I tried to run all of the tests? Now I expect to see a lot of errors, actually. And yes, as you can see, we broke everything else because none of the other tests are accounting for the authentication that we just introduced. Now, given that the entire application will be restricted by a logging, let's add a helper method to quickly sign in as a user. Let's open the test case class. This file is located on their the Tests folder on your project and let's at a protected function called Sign In. This will receive a user as a parameter, and here I simply say this acting us. They use that we just received, and finally we return this. This will allow us to keep changing methods. After calling signing and to keep things simple. I'm going to sign in from this set up method so that it is done for all of the tests. So I will call signing, and I will need a new use it. And actually let's have these user as a protected field, so we'll have any protected. Use it up here and down here. I will say this user equals, Create up, use it. And I'm doing it like this in case I need to use this user in any other tests. So let's pass this user as a parameter to the assigning method, and that should do the trick. And I should probably add a sign out method to make sure that guests are not allowed in the transaction speech. So let's go down and right after the signing method lists at another protected function miscall, it signed out, and here I was simply make a both coal to log out, and then that's always return this. Okay. With that in place, let's go back to the view transactions test in right before exception handling this called the sign Out method to make sure that the use it is not signed in then we enable exception handling. Visit the transaction speech in assert that we get redirected to the logging pitch. Okay, lets does that one copy the myth that name. Go back to the terminal test and filter and entered. And now we get green. But let's see if everything else is passing. So this test everything and we get green as well. Okay, that takes care of the first problem we had, which was not allowing guests into a transaction space only authenticated users. The other problem that we have is that we don't want to show all of the transactions in that page. We only want to show the transactions that belonged to the corn only logged in user. So let's add a new test for this in right below this one. Let's create another test and let's call it it. Only this place did in sections that belong to the currently logged in user, and I have a typo or right here. There you go. And I know it's a long method name, but in my experience, the more descriptive, the better. Okay, now let's start working on the test. First, we're going to need a user that will be different from the one that is currently loved in. So this call this all the user equals to create. Ah, use it Now we're going to need two transactions. One will be the transaction that belongs to the currently logged in user. Let's call it simply transaction. This equals to create that that in section. And we have to be specific about the user. I d. So you said I d. And for the value we say this, you said I d remember that we have this user viable, available from the set of method off the base desk case class. Now we need another transaction. Let's call it or that a transaction and this would be equals to create up did in section and again. Let's be specific about the use of writing. So you said I d will have a value off other user Heidi. Now we want to visit the transactions page using get but in sections. And here I want to make sure that I can see the Prince section description, which belongs to the currently locked in user. And also, let's assert the opposite for the other transactions so certain don't see or their transaction description. Okay, simple enough. Let's copy this method name. Jump back to the terminal, test and filter. Let's see what we get. Okay, The first error is that the table transactions does not have a user i d Color. Let's jump back to the editor and opened the migration file. It is called Create current section stable and again, this is located in the database Migrations folder in right Under the category idea. Let's say table, this will be again. An unsigned integer called You said I d back to the terminal in testing it. Now it's failing to assert that the render view does not contain the other transaction description, and this is expected because we are still not filtering. So let's go back to the editor and let's think how we can solve this. If we go to the transactions controller, the easiest solution will be maybe two at another scope. Call it maybe by use it or something like that, maybe past the logged in user here by saying maybe out use it. But if you think about it, there will be no situation in which I want to let one user see the transactions from another. So instead, let's make this a default by adding a global scope to the transaction model. So let's open the transaction model and up here. Let's at a public static function called boot in here, I'm going to register a new global scope using static that global scope. And it's called this user into the second parameter. We called a function that receives de query builder. And in here we simply say Query where you said, I d it's equal to South i d. This level helper method will return the currently locked in use already. And now every time we execute a query to the transaction stable, this condition will be at it. So with that in place, let's go back to the terminal in test again. And we have one a road, see what it iss uh, seems like I forgot to remove this dummy by user method is your back to the editorial. Quick back to the controller and let's remove this method from here. It doesn't exist, so that will be enough back to the terminal investigate. And now we get green. Let's test everything to make sure that we didn't break anything and it seems we got a few ever. So let's scroll all the way to the top to see what's going on in the first is in the it can create transactions. It's complaining because the transaction you sorry d cannot be no so a few things that we have to fix. Your first of all, we have to add the use that I d. As a fee level column in the transaction model. And also we need to modify the model builder to include that into the creation off new models. Let's go back to the editor, open the tent section model and at the end of this array, the feel of Hillary this pap, you said I d. Now open the model factory file again. This fire is located in the database factories folder and for the use of ready if not specified. Let's just call a function and dysfunction will simply return create. You said a class. We don't need this first lash from here and we actually need the use of I D. Okay, lets see that soft problem. Let's go back to terminal. I'm going to copy the method name from the error so that I can feel her for that one only copy. Then just feel it. It No, we're getting another error and scroll up to the top to see where it's happening, and it appears to be in the eat can create in sections. And it's complaining because the created transaction description is not showing up when we go back, too little sexual released. Let's turn back to the editor and see what's going on. This opened the Creator in sections Dist and look for the It can create sections, and yet this is obviously the problem We're making a nutrient section with this transaction will belong to a new user, which is not a user that is currently loved in, if you remember in the model factory, in fact, let's go back there real quick were saying that if we're not specifying a user I d. When either making or creating a new transaction, it will simply create one for us. But if we open the test case class in the set up method, we're actually creating a new user and then signing as that uses. Therefore, when we go back to the transactions page, the transaction that we actually created does not belong to the currently logged in use to some things. Problem. Let's go back today. Create transaction test and let's be specific about the use that I d. For the moment, use that i d. Everybody will be You said Sorry this Use it, I d Let's see, that solves the problem. This copy that method name. Jump back to the terminal test and filter. All right, that's solved That problem. We get green and let's see if we still have any problems anywhere else. We have another error. This time it's in Scroll back to the top. We actually have two errors. The 1st 1 is in. It can display all transactions Anything. The problem will be the same in this case. And copy this method name. Jump back to the editor and navigate to this method real quick and yet same thing. We're creating any transaction, but it belongs to another user. But now I'm starting to see a pattern. Every time I need to create a class, I need to assign the user by hand. But instead of doing that, let's add a couple of helper methods that will make our life easier. Open the test case class located in the Tests folder and down here, this Addy protective function called Make here we would receive the class that we want to make the overwrites which will be an empty array by default and how many times we want to make this glass. This is basically a replica off the make helper method that we have in the test helpers file. If you take a look at that, the signature is actually very similar. In fact, we have to make the time sequel snow. And the reason I'm doing this is because here I want to return the same method. Cole make spastic class, but in the overwrites, I want to do an array, merge and create an in line array off the user. I d. With the value of these. Use it. I d. And I want to merge that with whatever overwrites were passing. And finally we passed times viable. And now that we're here, let's create another one for the create method. So this will be called create and it will be pretty much the same, except that we return a call to the create helper method. Now let's go back to the beauty and sections test and instead of calling create that's called thes create, which is pretty much the same except that we're assigning the newly created transaction to the currently logged in user. And in fact, let's go to the Creator and Sections test and let's do the same here instead of calling make. It's called this make and we can skip these array and simply call it like this. And with that in place, let's go back to the terminal and let's run all of the test again to see if we still have any errors. We still have one. A road, I think. And it's located in the It can filter transactions by category, which is inside the view transactions test. Let's go back to the editor. Open the view transactions test. Look for the message. It can feel different sections by category. And here we have to replace create all of these instances of create with this create We're missing arrow here. Okay, there you go. So again, instead of calling, create, we're calling our version of create, which will assign everything to the currently logged in user. But actually this will fail because category doesn't have any user i d. So let's keep category as create and let's just apply those changes. Do three in section. Well, eventually do it to categorias well, but for now, we only have transactions belonging to the currently logged in users. Okay, let's go back to the terminal, test everything again and see if we get going this time. And yes, now we get rid. That should be enough for the speedy. So let's take a break here. And in the next video, we're going to create a view that will allow users to create new transactions. 11. 11 Create Transactions View: before we start working on the U I. First we have to take care off the live database that we're going to use, which is currently empty. As of now, if we navigate to our home page in the budget dot a PP, this is what we're going to get. This is the latter will default home page. And since we already scaffold at the authentication system, we additionally get two extra wings in this corner, which are for logging into the system and register new users. If we click on any of those, for example, logging, we get our logging page. And also, if we click a register, we have the ability to create new users. But problem here is seems the database it's empty. There is no use her stable. So if I try to do anything, I will get an exception like this. So to fix this, let's go to the terminal and run the migrations. But this time we will run them against the life database. To do that, simply type artisan and let me clarify. I'm only typing artisan because I am inside Homestead, which creates analysis for me instead of having to type Ph B artisan. I can simply type artisan, so to run immigration, simply type artisan migrate. If we hit, enter, Larible will create all of the tables in the system for us. As you can see, it created the user stable. The password resets transactions and categories, and additionally, if there is no migration stable, which issues for running and rolling back migrations, it will create one as well. With this in place, we can simply jump back into the browser. I'm going to navigate back to the log in page. And actually, I want to register a new user. In this case, Miss Cali John Doe with an email address of John Doe at tested come password secret. We confirmed the password again. Secret in click register Little bit creates the use of for US incentives to these you area , which is the default lateral home page. That was scaffold it for us. Now we can remove this home and actually navigate to our transaction speech in as you can notice the pages looking a little bit funky right now. And this is important because even though all of the tests were passing, the view itself is not exactly accurate. So let's jump back into the editor and see what's going on here. We will open sections index played up each bean and see right. I forgot to add a section called Content. So he we say section content in at the bottom and section and that should take care of it. Let's go back to the browser and refresh and yeah, nodded trick. So right now, we have a view for all of the transactions, but we don't have any transactions in the system, and that's what we're going to do now. We're going to create a view that will allow the user to create new transaction. Okay, let's go back to the editor and start work close itself. And I'm going to create a new view inside resources, views, transactions. And this will be a new PHP file called Create that blade dot PHP. Okay, the first thing wouldn't Here is to extend from the main layout. So extends layouts that a PP Next, we need the section for the main content, so section content and close it right away with end section. Okay, let's start with a D plus container that will give us a little bit of spacing on the edges . Next, let's at the form and the action will be the transactions. Your ill and the method will be post. Now let's at another thief, class form group. And here this at a label for a description in the text of it will be description and ray below it. Let's at an input with class for input. This will be an input of type text in the name will be description, and actually the classes not form input. It's actually formed control for the value we are going to use. They had better method cold old, and we passed the key description. And this will allow us to keep all values in case of validation errors. Next, we're going to use another input for the amount. So I'm going to copy this entire Dave and pasted right below. The label in this case will be for amount. Text also amount in the input. It's never be a text input. Instead, we're going to use a number in name amount in the key for the old method will be amount as well. Finally, we're going to need a drop down for the category E. So I'm going to base the same deep again. In this case, the label will be for category idea. Ticks can be cut, dignity. And we're not going to use an input. In this case, we're going to need a select. The name of this leg will be integrity, Dean, Class, form, control. And we can omit the i d. For now, in just for simplicity, let's at an empty option. Okay, that seems good enough. So let's open the routes file first and at a route for our new four open routes web dot PHP And here We already have a route for a post to the transaction. So I'm going to copy that one in right above it. I'm going toe a get requests were get route for the transactions. Your l and this should be handled by transactions controller. But in this case, the method it's called create. Now let's open determine sections, control it in at that, create myth it. I'm gonna added right about this storm. Is it here? I'm going to simply return. Then you view cold front sections create. All right. I think we're ready to go to the browser and take a look at it. So let's jump back into grown and navigate manually to trend sections. I made a mistake here. The actual route should be transactions create. So let's go back to the air Return six That real quick. Go back to routes. Weather PH. B. In these rush will be 10 sections. Create Cain. That should take care of that. Let's go back to chrome and navigate manually. Two transactions create, and we get a not found http exception. And I think I know what the problem is. If you see here is trying to look for a category. So if we go back to the editor in the routes found, if you notice we may the category parameter optional. So he's getting this route first, and he's trying to evaluate this route first. So he thinks that this creator can hear It's actually the name of a category. So to solve this, simply move the route. How about this one? So the lateral will first try to evaluate this route, and if he cannot find a route suitable, then he will move on to the next one. Let's come back to the browser and refresh in there. You that solves the problem and the form looks good enough. But there are a few things that I would like to add. For example, I would like to form to have a white background, and also I don't like it that expends to the entirety of the page. I'd like it to be a little bit smaller, maybe half a page, So let's work on the white background. First jump back to the editor in back to the View, file the creative plate of BHP and to give it a white background, I'm going to use a panel, a bootstrap Bannon, so simply create a deep class panel panel default. And inside, I'm going to create another thief class by heading and also a thief class panel body for the heading, Let's just say let's give it a heading off Create did in section and for the body we seem protect form and move it inside the panda boy. All right, let's see how that looks back to the browser. Alright, Looking better already. Now let's make this panel a little bit smaller. Back to the editor in its say right before the panel. Deve, the 1st 1 this at a dif class ro and inside a Deve Glass goal. M D. Six. Maybe if you're not familiar with Bootstrap, it basically divides the entire page in 12 columns. And this basically says that on a medium size display, this Dave will extend for only six of those columns. So effectively just half of the page. And I'm going to take this entire panel and move it inside this thief call M D six and let's see how that looks. And, yeah, it looks better. But I think it's a little bit too much to the left, so maybe we can offset it a little bit, maybe trying center it in the page. So let's go back to the editorial quick. And maybe instead of making it a six column. So let's try this instead. Let's make it eight columns, wife and then another class gold called M D. Offset in. Let's upset it by two columns. So let's see how that looks And yeah, that's a lot better. It gives the impression that the entire there is centered on the page, but it's basically just a deal with eight columns wide, and it's been offset from the left. Two columns now two things missing. First, we need to feel this category. Drop down with all of the categories in the system. And second, we need to add a button here for submitting before so back to the editor the state care of the but will first, which is easier right before we close it formed. Attack this. Add a button class B TN Bt in success so that it's ah, green bottle. This will be a type submit, and the legend will be safe. Let's go back to browser and see that looks all right. Now we move on to the categories, so let's go back to the browser in Let's jump to the controller, the transactions controller. So here I'm going to create a variable called Cut their Bodies in a Sign captivity. This will effectively bring all of the categories in the system into this variable. Now let's pause Theis favorable to the U by saying compact, cut their ways. Now we jump back to the view and in thes select name category, I d right below the empty option. Less iterating over the categories for each and we saved for each categories. Scott, dignity and I'm gonna close it right away. And for each and for each one of those, I'm going to add another option. The value will be the category editing, So integrity, Heidi and the text for it will be category name. So if we jump back to the browser and fresh, there are no errors. But still, we don't have any categories in the system yet. So instead of going to the database and manually create categories, I'm going to take an easy route, which is simply see the database with dummy data. So let's jump back into terminal in type artisan. Think it. And since we have a very handy helper for creating categories using modern factories, we can simply say create AP category and let's say we create 10 categories. All right, let's see that works right. The first parameter, which is this one, is actually a list of overwrites or attributes, but we don't need those. So instead we're going to pass an empty array, and then the number of times is the last parliament, despite that again and now we have 10 dummy categories in our database. So if we jump back to the browser and fresh, we should see this category drug them we 10 dummy categories that we just create. Now the beautiful thing about this is that since we already covered the functionality for creating categories during our testing, in theory, I can start creating transactions right away. Let's give it a shot for the description. It's a Destin section was given an amount off $15 and select any category perfectly safe. I should be redirected to the transactions least, and I should be able to see my newly created transaction. So let's try it. Click safe and we get an exception. But this is an easy one. We forgot to include the CS R F talkin in our four. So let me navigate back and jump into the editor. So for every form that makes pose requests, we must always include the CS R F Field in thes Handy Mattered will render it for us. Okay, back to the brown serialised. Give it a quick refresh. Let's try that again. Distance section, $15. Any contiguity safe. And now we have another problem and it's saying that the user I d cannot be No. And as you remember from the test, whenever we created new transactions. We were assigning the use of right the by the fault to the currently logged in user. We're not doing this into four to sell these. Let's go back to the editor in right at the end before the button. This at a new input in this case, would be a hidden input. Please give me the name off. You said I D. And for the value, let's say house I D, which will give us the I d off the currently loved in user. All right, one more time. Let's go back to the browser, navigate back, give it a quick refresh, distant sexual, $15. Any category safe and great. Now we can see the sections least, and we have the new transaction listed in the table. Now let's go back to the editor real quick because there is something I don't know now. I added thes for a quick solution. But instead of having to at this hidden input for every form every create form in our system, let's do something better. I'm going to remove this from here, and instead of doing and like that, I'm going to create a model event because if we think about it. There is no situation in which the user that is submitting the form is not a user that is going to own the data. So let's open the transaction model and we're going to use something called a model event model events are away off tapping into the data that has been saved, updated or deleted right after or right before the event this actually happened. So in this case, I want to modify the user. I d. Right before I'm going to say the data to the database. So inside this boot method, right after the global scope, I'm going to say static saving in this method will receive a callback function, and this will receive the transaction that we're saving to the database as a parameter. And here I can say that section you said I d equals to the 10 section use that i d. If we provided one before saving. But if that when it's empty, I will use out i d. So again, the basic idea is right before saving the transaction toe the database. If there is no use that idea available, I will take that I d from the station All right, let's try that again. So let's go back to the browser one more time. Navigate to transactions. Create in the screen. Another transaction, Let's say $20 in any contiguity. Click safe and it's working. We're not using any hearing input. Instead, we're using model events, and we're using specifically the saving event, which occurs right before the data is persisted to the database. Now from the test, we were also checking. If we send invalid data, we will get Evers. But if we navigate to transactions, create one more time. And if I tried to submit this without any data, the four will simply take me back. But I see no indication that there was in Europe. So let's try and fix that. Listen back to the editor in open D, create view in Lister with the description. Bootstrap has a handy has error class that will highlight the entire field in red if there is any error. So let's make this condition this open enclosed double brackets. And remember, if we have any validation errors in Lauraville when we get redirected back to the form page level will also create a variable called errors automatically so we can use this viable and say if errors has description, then we print down. The class has error, and if it doesn't have any errors for the description, we simply output and empty stream. So again, these errors variable is created by lateral automatically whenever there are any validation errors in our control it So if we take a look at the controller in the store method, we're making this call these evaluate. If this fails level is going to create a errors variable and make it available in the view . Let's go back to the view and let's use the same logic for the amount So right after the form group, But right before you close the double quotes copy and paste that. And instead of asking for description here, I'm asking for amount. Let's do the same for category. So right after form group based that in instead of description is look for integrity. I d. All right, let's see how that words Let's go back to the browser and try to submit the form again without any data. Now I could take him back to the form, but the fields that have errors have been highlighted in red. So if, for example, I had a $20 amount in select integrity, the description is still needed. So if I tried to submit like this, I'm taken back to the form in the description is still highlighting in red. Also not is that since we're using that old method, we don't have to type that $20 again, only the data that is needed. But we actually lost the category, so we have to do a trick for that as well. Jump to the editor and in the select when we're iterating through the categories right after the value. But before we close the attack right here, let's open closed off brackets. And if the category I d, it's equal to old category idea, then we all put the string selected. Otherwise we simply output and string. Let's try that again. Go back to the browser, select any category and against of meat without a description, and now we are taken back to the form. The description is still needed, but we get a category already selected from the previous election that we make. All right, we're going to take a break here, but in the next video. We're going to make some enhancements to the U I. Because as of now there is no way to reach this form without having to type the U aerial manually. Instead, I would like to add a link from the transactions leased to the create for, and we're going to take care of that in the next lesson. 12. 12 UI Enhancements: Okay, let's add a link so that we can reach the create form without having to manually input the Eurail in the browser. This will be the entire navigation bar. The section here will create a hamburger. Buttle. In case we're looking at the page in a small device, These will be the rounding image again with the name taken from the configuration. And actually, since we're here, let's go ahead and change these. This is taken from the main at configuration found. This is located under con fiqh up the pH being. So if you take a look at that one we can see here is the application name that's changed these to budget. Go back to the browser and see how that looks. And yet it changes here in the navigation bar and also in the pace title. All right, great. There's no one. Go back to the ab layout in here. You can see the left side of the navigation bar in the right side of the navigation bar. The right side contains the authentication Ling's If you look at the roads are here. This is the right side. If you're logged in, it actually gives you the user name in also a log out link. But I would like to have my link right next to the branding image somewhere around here. So that'll be the left side. And here inside this u l we can simply add another item. So I inside this list item, we can add a link in this link will take us to transactions. Create. Let's give it a text off new Prince section. All right, let's see how that looks. Roberto. Browser and refresh. We have a new link here, and if we click on it, we go to the creator in section for Great. But now we don't have any way to go back to the transaction, least if we decide not to create any protection. So let's add a new link right before this one that says older in sections back to the editor and its copy this least item in our a new one right above it in the link will take Stoute sections and it's give it a text off all transactions back browser in, See how that looks Refresh. And there you have it. Now we have a link to reach distant section least and Also, we have a link to create a new transaction. And since we are in the topic of enhancing the you, I, the transaction least will benefit from a white background as well. So let's jump back to the editor. Open the transactions. Index page in. Right for the table is create another planner. It will be a thief. Glass panel penalty fold another dif with glass panel heading and finally, Deve with glass panel body. Actually, I don't think we need heading for the spaniel. Solis removed that one. And inside the spinal body, we take this dif cut and paste it in here to go back to browse and see how that looks. Yeah, a lot better. All right, let's take a break here. And in the next video, we're going to give the user the ability to update transactions. 13. 13 It Can Update Transactions: Okay, so let's take care off anything a transaction that we already created. We're going to create a new file under tests Feature. This will be a PHP file, and I'm gonna call it of the transactions test. And here I'm going to create in your this glass, which is basically just a glass of the transaction tests which extends from test case in uses that every migrations in a quick note on this, if you notice I didn't use the artists and command for making a test, but that's another way to do it. In fact, let me show you how that would work. Going to delete the file real quick and let's go to the terminal. And the way you scaffold your tests usually is by saying artisan or PHP artisan. Make this and then the name of your class will be in this case update. They're in sections. This If you live in like this, it will create a class inside the tests feature folder if you want to create this class inside the unit folder simply at a stash stash unit at the end. But in this case, we don't need So if you hit, enter like this. It says Desk created successfully. So let's go back to the editor. And as you can see, it created our class here. Now, if you take a look at the file, it's pretty much the same file I had. With a few minor exceptions, it creates a scaffold of a test for you. Except that I don't like this naming convention. So I always change it. And the other differences that I'm not including some of these dependencies because I don't need to. Only the database migrations one. And also, I almost always forget to use database migrations in my class. So I run the test and find out, and I go back and add it. So I lose some time on that and also the method name. I don't like to use thes convention. I always like to use the decorator test and the name I always like to name it it something so we don't the unused tendencies, and basically we end up with same test class that I had before, so instead of having to do all of those edits over and over again instead, I created a code snippet in my editor. I am not going to go into details on how to create code snippets on this editor because you may not use. I am not going to go into details ever how to create code snippets in this editor. Just know that every time I created test class, I'm not going to use the scaffolding method. Instead, I will create file manually and then simply say test class in that we'll scaffold the entire disc less so with that out of the way, let's start with test. First of all, I'm going to need a transaction. So the section equals this make? Actually, no, we need a already created that away so thes create ap different section. And now we need another transaction that we're going to use to update they already created one. So let's call it new transaction. This will be equal to these make Aptidon section. Next. I'm going to send a put request with these put and that will be a request to transactions and then we need to include the transaction, I d. So instead, off single quotes, I'm going to use double quotes and here I can say open close bracket. This is speech bees way to replace a variable within a string in the section I. D. So when PHP evaluates string is going to replace everything within the brackets with the actual value of the I D. Then we send the new transaction data. We send that as an array, and if this is successful, I expect to be redirected to the transactions least, so reassert redirect to transactions. Finally, I want to assert that if I visit the transactions page, I should be able to see the new transaction description. So this get there in sections in a certain see nutrient section description, and seems I forgot that method names or let's call this method it can update, but in sections. Okay, that should be enough. So let's go in test. Copy the method name moved to the terminal test filter. It can update in sections. We get a method not allowed http exception, which is pretty normal because we don't have a route yet, So let's go back to the editor. Open routes whip the pH being, and let's add the route down here, so this will be route put in. This will be to Trinh sections and then we received it section in the euro. These should be handled inside transactions controller specifically in the update myth. And obviously this doesn't exist yet. But I'm going to let the test tell me that so that I can then go in and fix it back to terminal and test again. All right, screw up to the top in a suspected the method out the doesn't exist. So back to the editor. Let's open the transactions controller in them. Here, let's create a new public function called update. And with that, let's go back to the editor in Test one more time. And this is a pretty normal error again. Response status Code 200 is not a redirect status coat. This is because the method is empty and he's expecting a redirect so to the editor one time in, Let's return redirect to but in sections again, I'm just writing the code that will take care off the current error. I'm not writing ahead. I know that there is a lot to be done, but for now, and this is the general work flow that you should follow is solved of current problem and then move on to the next and the current problem is that he suspecting a redirection toe the transaction speech. So with that taken care off, let's go back to the Terra meaner in test one more time. And the next error is that he's failing to assert that the render view the transaction least has the new transaction description, and that is because we haven't created it yet. So to fix that, we go back to the editor. And first of all, we need to receive the transaction as a parameter because we are using implicit model binding. So we simply type Hinde transaction and passing a transaction parameter, which is the same name that we use in a route. Let me show you back to the rally, and we are respecting a transaction parameter. And since we are using in policing model binding, if we type hint that perimeter with the same name, Maribel will use the I D passed in the perimeter into a search in the database to retrieve the actual transaction. Now we want to update these transaction with the data from the quest, so we can simply say the in section all date and then passed the request, and in this case, we can simply say or so with that in place, let's go back to the terminal in test one more time and we get ring. Let's test everything to make sure that we didn't break anything in the process and we still get exit. Now we're going to take a break here, but for the next video, I'm going to leave you an assignment. If you remember, when we created the tests for creating transactions, we also created a set of tests to make sure that data that we're sending can be validated. Let's go to the editor to show you I'm going to open the creator in sections test in down here. We created all of these days to make sure that we cannot create transactions without a description without integrity and without an amount in all suit made sure that the amount was valid. So for your assignment, you are going to create all of the validations that will make sure that you cannot all day transactions without the value data. I want you to follow the example from the creator in section test and create similar tests . But this time inside the all day transactions test. So down here. You will create all of the tests to make sure that you can not all day transaction without a description, without the integrity and without an amount. And also make sure that when you off the category, you cannot do it. If the amount is not that in the next video, we will go over the solution. And also we will work on the form that will allow users to update transactions from the USA . 14. 14 Edit Transactions View: in the past video, we left you an assignment to create the validation tests for obtaining transactions, so I hope that went well. Now, let's quickly go over the solution or at least my version of the solution. Hopefully, this will compare well to when you did. So the first thing I'm going to do is I'm going to quickly switch to create transactions, test and remember that here we created a hell permitted for posting a transaction. We're going to create something similar, but in this case, we're going to create a transaction, then updated. Return that and then assert on the valuation errors. So I'm going to steal this piece of go the poster and section from here back to the update . Transaction tests paste it. Here. In this case, I'm going to call this update in section. And yes, we're going to need one with make to create the new data. But we're going to call this actually new transaction in to make it simple. It's just copied these two lines from the previous test and just based him here. And I'm going to also copy this put line from here and then return that with the difference that we want to enable exception handling. So to sum up, we're creating a new transaction persistent to the database, then creating a new set of data for the nutrient section. Then, with exception handling enabled we send that data to transactions, drank sanction. I d send any later over and we don't need this. Assert. Redirect. Take that off. Okay, so we that helper makes it, We can start with the tests, so I'm going to switch back again to the creator and section tests. And let's look for the first test, which is the validation of the description. I'm going to copy this entire test switch back to off the transaction test. Copy. Sorry. Basted here. And instead of calling post in section is called off day transaction and I think I should do it. The only thing that remains is to modify the method name. So let's call it he cannot update transactions without a description. Skopje the method name. Switch back to the terminal test and filter going to see what we get. Okay, we get an error saying that decision is missing the Eroski, which is expected because we're not validating yet. So back to the editor. That's open D trinh sections controller. And to make things simple, I'm going to copy this validation from the store method based it right above the update line. Now granted, I'm skipping ahead a little bit because I haven't written the tests for evaluating the category for the amount. But since it's just a copy paste, it's not really that big of a deal. It will actually save us some time when we get to writing the category I devaluation in the amount validation. So with that in placeless, jump back to the terminal in test again and it's still not validating. That's strange. Let's go back to the editor and see what's going on. The valuation looks good. It's actually the same as we used in store method, so that's not it. Let's go back to the lovely transaction test to see if we missed something. We are updating a transaction sending Oh, there it is. I am not actually overriding the description when I'm making the nutrients section. So after the make or in the make, I have to actually pass the new overwrites. So that description is missing. Okay, let's go back to Terra meaner desiccant. And now we get agree. Excellent. Okay, back to the editor. They should be quick. Now, I need the rest of valuation method. So I'm just going to go to the transactions The created in sections test and copy the rest of the validation methods that we need. So it'll be the creator and sections without integrity created in sections were amount in, create sections without a valid amount. We're going to copy those three and paste them right after this one. Now, I'm going to replace Boast in section in the three instances with of the section and instead off create. I'm going to replace that in the three Method names with update. So what we end up is it cannot update transactions without a category. Can it? Off data in sections without an amount, and it cannot update transactions without a valid amount. So instead of having to test all of those three individually, I'm just going to scroll to the top. Copy the class name in this case, switch toe, terra, meaner test and fielder. But in this case, instead of the method name, I'm going to filter by the class which will execute all of the tests within that class, and we get green. All of my tests are passing great. That was quick. All right, with the validation out of the way, let's go back to the editor and start working on the form or the view for updating transactions. Now it's open the turn sections create view. So instead of replicating the entire form just for the all day, why don't we make the entire form reusable and therefore avoid unnecessary code repetition ? I'll show you how, first of all in the resources views turn sections, I'm going to create a new PHP file. Let's call it forum dot blade that PHP This will serve as a partial view for the four. Now I'm going to steal the HTML from the create form, and I will take everything in between the foreign tax, including the CSR field. I am not going to copy the form tag itself because the girl for the update and create will be different. So I'm just going to get everything in between, including the bottle. I'm going to cut this jump back to forms of later beach, be in basic here Now there are a few things that we need to modify. For example, starting with this. This all description worked well when we were creating data. But when we are updating the transaction, we actually need the value from the database or the data that we input in case there is any validation errors. So what we can do? ISS. We either display the old value and we're going to use a question mark column, which is a binary decision which will either use devalue on the left side. And if that's not fine, it will use the value on the right side. And in this case, we will need the actual section description. Because in a update scenario, the transaction should have been passed down to the view. We will do the same for amount, so either the old value for the transaction amount in for the category. Instead of just asking for the old value, we're going to enclose these in parentheses, and then we either compare it to the old value or the actual transaction. Category 80 and this line just got a little bit too long. So I'm going to take this down here in dentures, aligned this one down here and Finally, we have to do something with the button text because if we are updating, we don't want to say safe in the button. We actually want something like update. So why don't we use a viable that we are going to later inject into the sparse show view so we can open and close brackets and say, If we have a value defined for the text button, we can do that with a reset button text. Let's say that's variable for us. If that it's said then we simply output that value. Otherwise we'd fault to save. Now how do we use thes in the previous form? The one that we stole this cold for the create for? So let's go back to that. The creative later Ph. B. And in here we can use a blade directive called Include. And here we can Pass Down the View name, which will be transactions 0.4 transactions. His folder inform is the actual view name. Now what happens if we go in testis in our Roeser? Cassidy's This switch to the browser, and I'm already in the transaction. Least let's go to the new transaction For now, I was expecting this to happen because we used the transaction viable in the view, but we were kind of hoping that we were using that when updating a thin section. But what happens when we are creating a new one? Well, the simple solution is to jump back into the editor, open the transactions controller, and in this create method, let's just simply insane She ate a name, t transaction begin simply state section equals two new transaction and then simply passed that down to the view. And that will eliminate the problem because we are referring to an empty transaction that has no values. So there would be no problem with that. So back to the browser in this refresh deceived the province gun and yeah, There you go. And now the creator and section works a suspected. As you can see, it falls to say, Tex for the method. Sorry for the button. Because we didn't specify any when including the partial view. Everything else works the same. Now let's work on the update form. So back to the editor, we're gonna close this one out. And now inside the view Sorry. Resources view student sections. I'm going to create a new file PHP file and I'm going to call it up the that blade got BHP and again, I'm going to borrow the A c m l from the transactions create the later PHP. Simply select everything copy and paste it here, and I'm going to change a few things. First of all, the title for the final heading should be of data section. The action for the form should be sections and then Dietrich section I d. So I'm expecting it section to be passed down. So turn section I d and also notice that the update works with a put request. Let me show you, is opened the routes web, the beach beam. And here we are expecting a put request. No repost request. So to simulate a put request weaken do it with they help permitted from never called method field. And in this case, we're looking for a put. And ultimately, all this is going to do is to render a heat and field called underscore method with a value off put in when level gets the request. He knows to interpret that, and instead of handling a post, he's going to say no. This is not opposed. This actually a put method and will use the appropriate route now. The next thing we want to do is to send the button text into these view, and we can do that by simply passing a second parameter, which is an array off key value brightens. In this case, this will be the variable name, which is button text, and the value will be update now. The next thing we want for this is the route. So let's open the routes file. And I just realized I named the View incorrectly because if we open the transactions controller, we already have an update. But that abilities for the actual updating of the section. So let's rename the view that we created resources views Trinh sections instead off update this call this edit. So I'm going to rename this to edit that played at BHP. All right with that, out of the way, let's go back to the routes file. All right, let's add the route for our form so it's added at the end route. Get your rebel beat sections and it's passed in eight section that we want to edit, and this should be handled by the sections controller in the edit method. Now hope indeed, sections controller. And let's add that method at the end. Another public function called Did It? And this will receive a transaction using implicit mother finding. And in here I'm simply going to return a view code sections edit and then passed down detained section. Now, before we move on, I would like to have a way to reach this edit form from the transaction least. Otherwise I will have to know by memory, which is the idea of the transaction that I want to edit. So to do that, let's quickly open the sections index and let's turn thes description into a link that will take us to transactions. In this past V transaction, I D. In move this intact from here to here. Okay, let's see how that looks. Let's go back to the browser in click on the sexual Least Order in sections, and now the transaction description is actually a link to the update for Let's see that works, we click on it and we face the same ever that we face a few feet ears back, and this is because this is trying to look for the get method of transactions with a category instead of looking for the right road. So So that list jump back to the editor again, opened the weather beach, be for the routes. And again, there is a get method for transactions with a category parameter that is optional. So he's speaking that up before choosing a get for the transactions. We didn't section is apparent so that simply get this route and move it to the top. This jump back to the browser and refresh. Of course, I forgot to pass down the categories for the categories in the drop down. So back to the editor in this open the transactions controller. I'm going to borrow this line from here. Actually, no. Another transaction, the categories. So copy these, paste it here and then passed that down to the view. Okay, that should do the trick back. But l said and refresh, and it works. We have the values from the Korean transaction populated in our fields, and the text is actually updated to say of the We're going to take a break here, and in the next session, we're going to take care off the leading transactions 15. 15 It Can Delete Transactions: All right, let's add the ability to the literal sections. I'm going to create a new test class, and this will be in test feature in a creating new PHP file is call it delete Transactions test in here. I'm going to use my code snippet to create a new tits class called Transactions Test. It just extends from DSK's and uses that are is migrations. Now, the first method will be gold. It can delete transaction in. First of all, we need a transaction to the lead, so section equals create up front section and then we say this delete to send a delete request to transactions and then the transaction i d. But I remember that we were doing this in double quotes. Correct that quick and again, I'm using double quotes because these viable replacement method only works with double quotes. If you try to do this in a single quoted string, it's not gonna work. So, like I said, I needed section I D and one status complete. I respect to be redirected to the transactions. Wiest Also, if I visit the transaction least with this get in the U area will be sections I should not be able to see the transaction description because it has been deleted, so assert Don't see transaction description. Okay, that's simple enough. Let's go ahead and test Copy this method. Jump to the terminal test filter. The red we get our first error in it is expected because we don't have a rowdy it. So we get a method not allowed http exception back to the editor. Open routes were that ph mean, and I think we can put this safely at the end. So this will be route delete transactions and were respected to receive eight section as a parameter, and this should be handled by transactions. Controller Destroy. All right, now that we have that route back to the terminal in testicles and I'm expecting to have in every because the story method doesn't exist. So back to the editor in its open their transactions controller and right at the end, let's at a new public function called destroy in this method will receive a trinh section with implicit model binding, and that should be all for now. So back to the terminal intestine. And we still have a never lets see what's going on here. No, query results for model APP transaction since, like the implicit model binding is that finding a result for the past transaction idea. Let's turn back to the editor to see what's happening. So we're Cohen. Oh, of course, we're calling the Create Helper method, but this creates a transaction under a different user. So when the implicit model binding is trying to find the section is not going to find it, because we have a global scope that says that we only are allowed to find transactions for the currently Longtan user. And that was my mistake. We have to use instead thes create method, which is a help in a matter that we created a few videos back to help us create transactions under the current logged in user. Okay, let's see if that works back to the tear Amina in testicle. All right. We moved on from that error and now we're receiving the response status. CO 200 is not a redirect status coat. And as we know to fix this, we simply go back to the controller. And here we return a redirect two transactions, so there will take us back to the different sections least okay, Back to the demeanor just again. And looks like I missed the s entrance sections when I was redirecting sections test again . And now I think we erect to our final error, which is the failure to a said that the page does not contain the transaction description. So or we have to do is to go back to the editor, and right before we redirect, we simply say, Turn section delete. Okay, Simple enough back to terminal. And I expect to see a green code after this cell test again. And now we get with excellent. Let's test everything, just to be sure. And apparently we have another error. Let's see. What's that about? In view Transactions test. It can feel to return sections by category. No query results for model app in section. This sounds like the problem we face with the order of the route. So let's go and check that out real quick. Let's go back to the editor and let's open the routes File in routes. Weapon pH. Being so yeah, E tries to match this route first before even match in this one. So the student slits move the kid transactions section and take it from here and put it right below the trend sections category. Okay, let's see if that works just everything again. And yeah, that was problem. Okay, now let's move on to the view because now we know that begin to lead transactions. But we need a way to do it from the user interface. So let's go back to the editor in open the view for the transactions, least which is transactions Index. Okay, I'm going to add a new column, so I'll start with Heather, and that's called is removed. And down here, let's at the color. So another TD All right here. I'm going to add a small form that will trigger a Delete Co whenever it's clicked. So let's start with form. The action will be they're in sections, and then we passed the current section I D. In the method, we'll be boast, and here we are going to use the same technique we use with the boot method. We're going to simulate a delete request using a lot of ills Method field, and we want they delete also in every form that performs post. We can't forget. This year's are at field and Finally, we want a button. This will be clasp et en BT and danger to make it red and also be tiene Bash X s to make it extra small. Let's make this a type submit and the text will be delete more. Actually, let's make it more in line with the column. Heather so removed. Okay, let's see how that looks. Let's go back to the browser and let's refresh. Now we have a remove button for every item in the least. And since we already tested, if we click one of them, I should respect the item to be removed. So let's give it a shot removed in there. You and that takes care off, removing transactions now. The last thing I want to add to these view is the ability to imagine eight records. Fortunately, level makes is very simple. All you have to do is just go back to the editor, open the transactions controller and look for the index method. And right here, instead of saying get, let's try imagine eight. Now we open the view for the transaction least, so transactions that index that later speech being and right after the table close, intact we can simply say, but in sections links. And to see this in action first, I'm going to go back to the control it in just for the sake of testing and going to imagine eight with the page size off one. That means that we are going to get pages off one record each. If you don't provide this letter will imagine eight by the fault by 15 records for each page. But for now, let's just leave it at one and let's jump to the browser again. And for this test, I'm going to need to create a nutrient section. So let's call it another 10 section in a moment. 34 that they would be Nemo. Sense nice in safe, and now you can see that level will render a nice component right below the table with links for each page. In this case will be, too, because we have two records and also a couple of links for previous and next. Now, if we go back to the Editor Interactive's back to the default, which is 15 when we come back fresh, the component will not render because only two records means we have only one page, and we're going to take a break here. But in the next video, we're going to add a few more enhancements through these view over here. For example, we already created the tests for filtering by category, but right now we have no way of doing it through the you I. If we wanted to do that, we will have to manually input the integrity in the Ural like this Nemo, for example. And that would just keep me one record so we know that it's working, but we need a way to do it from the U. Y. The other enhancement I would like to add to the transactions list is the ability to filter by any given month, so we'll take care of that in the next lesson. 16. 16 Filter Transactions by Category & Month: The first thing I want to add to the transaction least is the ability to filter the transactions by category. As I said before, we already know this works into them and straight. We can passed in a contiguity on the URL, and it immediately filters the least by that category. But we don't have a way to do that on the U. S. So the way I want to do this is I'm going to add a drop down link on the top Heather, which will display all of the transactions. Sorry, all of the categories in the system. So when you select one, it will filter by that category. Let's jump into the editor and open the layout file, which is the one that contains the top Heather. This file is located or resource is views, layouts and finally school a PP dull blade of PHP soap that one up in right after the nutrient sexual least item this at a new this item. With the class off, drop down and inside, we are going to add a link with a class off drop down dash Targo. It was just at a hashtag to the location for the destination for the link. Then we need to add a data, their struggle with the value off drop down. Then we need to add a role equals button and finally, area expanded equals false. This means that the full state for the drug down is collapsed, not expanded in here. We're going to add label for the drop down, which would be categories, and immediately we need to expand with a class carrot. This will be the little carried that will show if the menu item is expanded or collapsed. And right after the link, we had an owner that at least so you will, with a class off drug down dash many and we give peace a role equals menu. Next, we need to reiterate over all of the categories in the system. So to do that, we simply use for each and here again, simply reference the category moral class. But we have to use the fully qualified name. So ap category E o. This will give me all of the items for all of the categories in the system and I will be treated. Ask Gregory and I'm going to close that right away with end forage now for each category, we're going to render a least fighting so he'll e and in here we add a link which will take us to transactions. And then the categories log. So they would he slug. And for the label we used the category name. Okay, let's see how that looks. We turn back to the browser refresh, and now we have a drop down with all of the categories in the system. And if we click on one, actually, let me go back to all of the different sections first, and let's click on these category right here. So we look it in the list. Here it is. And if we click on it right away, filters by that cattle. Okay, now what we need is to filter the least of transactions by any given month. And to do this first, we're going to create a test because we don't have a test for yet. So let's go back to the editor and let's create this in the view transactions test. So let's open view transactions test and down here I'm going to create a new test called it can filter transactions by month and in here basically What we need are two transactions one for the Korean month in one for the last month, or maybe two months back. So let's called one current transaction in this equals to these Create up there in section and then let's create another transaction is call it past transaction. This will be equal to this create after in section but here and going to be a specific about the created at column. And let's say this equals two carbon now, which will give me the current date. And to that, I'm going to say abstract a couple of months so sub month and then two. Okay, so this would give me a pastor in section, and now all they have to do is to visit the transsexual knees. So this get in the euro will be sections. And let's say we want to pass the month or the parameter in a query string. So question mark the same month equals two. And here we have to make the decision about how we want to pass a month since I really need the months, not the day or the year. Let's try passing the months as a three letter former so for example, it could be months, Jan for January or a you G for August, and I would like to pass this exact they 82 months from now or two months back, actually. So I'm gonna copy this and concatenation to the UL, but I'm gonna add a next recall to form at this capital. M will give me a month with a three letter format. So if I do this, I should be able to see the best transaction description, and also, I shouldn't be able to see. So, sir, I don't see the current transaction description. Okay, that should be enough. So let's copy the method name jumping to the terminal test and feel better only by that one , and let's see what we get, Okay? The first error says that he's unable to assert that the page does not contain this transaction description. Basically, he's showing both of its own sections, so he's not filtering. So let's go back to the editor in fixed that let's open the transactions controller. So, transactions controller and in the index method, what we're going to do here is, instead of calling paginated right away, I'm just going to remove that paginated call and with this by category will return is actually a query builder. So I can say this instead of ST Transactions. Let's call this Transaction Square E. And then I can make decisions about adding extra parameters or extra fielders to the query . For example. I can say, if request has month, then I can feel terror by the months To do that, I can say the in section square e where and then filter by, created at into filter. By the specific month, I'm going to basically do a query saying that the created at column has to be greater than or equal to carbon parse. And in here I can say first day off and then passed the request month and this be consistent with quotes that will be single quotes. Sorry. We also need to add another query. Another wear created at has to be lower than or equal to, and in this case, I'm gonna copy this basted here. But instead of the first day of the month, I want the last day of the month and then down here we can say sections equals two that in section square. E imagine eight All right, let's see that works. Let's go back to the terminal in test again. Excellent. We got green now. List ist everything. Just sure, And we still get green and everything is passing perfect. Now what we need to do is to add the ability to filter by months from the U. A. E. If we moved to the browser right now, and let's say we click on all transactions to eliminate filter so these two transactions were created in a tub. Erso. If we try to filter by month, let's say January it should give me an empty leased in. Yeah, that's working. Okay, let's add the ability to do this from the U I. And I think what I'm going to do is to add a small drop down, maybe in this side or in their side, and then have the users select one month from the drop down in Seattle, filter the entire list. So let's go back to the editor in Let's open the Transactions Index, the bladed PHP and let's see where we can at this Well, we have a panel already, so maybe we can make use of the battle heading so right before the final body. Let's at another Deve with class panel heading. So let's start we they row. So leave glass row and then another dif I'm going to make this two columns white so called MD to and then I'm going to offset this by 10 calls, so that will make it aligned completely to the right. So coal MD upset 10. Next, we will need a form, and we don't need an action for this because we want to form to submit to the current page . And to do that, we simply or meet the action. We do need a message and that'll be get and let's at an idea Swell, Solis called these months. For now, we need a select class form control. The name will be month, because that will be the perimeter added as a query string to the current page. We can have the same i d so month, and then let's at a little bit of JavaScript here. So every time, let's say on change equal stew document get element by idea month form sub meat. This will allow me to serve me the form automatically when a selection is made, since it is only 12 elements. I'm going to go with a hard coded method, but you can also create an array in the controller and pass it down to the view if you want whatever you find more comfortable. So it was at first option value. January or J. A n three letter months. Let's have the full actual month name as the labels January. The one thing I would like to have is, for example, whenever I select a month from the drop down, the page will refresh. So I would like to keep that selection the next time the base shows. So we can do this by probably passing a variable cold Corrine months. Maybe any of the current month equals two January. Then we mark this as selected other ways. No, sorry. First, when he's a question mark. So the current month is January. We select this one, otherwise we simply output and entry string, and I'm going to skip ahead a little bit in just at the 12 options to the select. I'm gonna bore you with the process because it's kind of repetitive, so I'm going to skip ahead a little bit and show you the 12 list items already at it All right now, we have all of the months added to the select from January to December. So let's go to the browser and see if this works. Let's refresh. And yet, of course, we're missing the current month. So we have to add that back to the editor in Open, the transactions controlled. And here we have to define the Qu'ran months parable and that probie. Let's see. So Corrine months, it's either the value that comes in the request as a month. But if nothing comes in there, probably want the current month or the month that were actually in. So maybe we can use carbon now. And informant that C three letter months. No, no, we have to do is pass this down to the view current months. All right, let's go back to the Brown said, and see if that works. Okay, we are actually in October at the time of this recording, so it is already selecting the current months by the fault. But we probably need to add some extra tests because right now, even though the current month is selected, it is not actually filtering by that month, either where many transactions here created in September or December or January. It will simply display them all, not just the ones in October. So we'll add that in a moment. But for now, let's test this in select maybe June. And yet the form is submitted automatically, thanks to that little JavaScript code, we added, We're passing the month in the U. R L and the transactions are being fielder. But since there are noted sections for Jim, we simply get an empty leased. So this timeless actually select double in that will feel terribly transsexual, least backed over, and we get the two transactions that we had before. Great. Now let's add an extra test to make sure that the least will always be filtered by the current month by default. So back to the editor, let's open up the the uterine sections test and down here, let's at a new test and let's call it, it can filter. They're in sections by Kuerten, month by default. So here, this is actually pretty similar to the previous test. I'm going to copy the whole thing based it here, but this time the transaction that I actually want to see he's the current section because we're simply going to visit the transaction speech without any parameters. Solis Invert this assert Psi Corps entrance section description in a certain don't see past didn't section description. Okay, that should be enough. The scope of this method name back to terminal tests and filtered and let's see what we get . Okay, it's telling us that it is not able to assert that the page doesn't contain this transaction description, which means that it's showing us both. So let's jump back to the editor and solve that problem. Let's open the transactions controller and looks like we are going to need an else here. So if the month has not been provided in the request, we're going to take this coat from here pasted here, and we can say the first day off this month, which will give me the first day of the current month. Same down here and we are missing a couple of Prentice's here in here. So with this in place, let's go back to terminal in testing it right. We get a green novelist ist everything okay, we get green. So let's go back to the editor and I want to get rid of all of these lines here because it's starting to look a little bit ugly. So how do we want this to look? Let's use a little bit of wishful codings. So instead of all of this, maybe I just want to say conceptions, query and maybe a scope called by month. And we passed the request month. That's it. And if we don't have a month and the request, simply say same thing by months. But we passed this string this month, and that actually looks much better now. Let's work on this by month scope. So it's open deterrence sections model. So Riveter in section model and down here, rebel O scope Bike dignity is at a new one, a public function cold school by month. And this will receive the query and also the month string, which will default to this month if nothing is best. And since we're going to default this month, so maybe we can go back to the stroller and just don't pass anything here back to the model . So this will be query where created at greater than or equal to. Then we use carbon parse here, we can use double quotes, actually, first day off month and then another where created at this lower than or equal to carbon pars last day off months. And this will be either the given month or this month by the phone. Okay, let's go ahead and test again to make sure that the every factor didn't break anything. So test everything and looks like we broke a lot of stuff. Seven failures. And see this 1st 1 it can feel this prince sections by current month. So it probably has to do with the last change that we did. That scope sold is going. Check that right away. Make sure I didn't miss anything a month. It's fine created at Raider. Oh, look at this. Mr De, over here. Okay, let's go back to the terminal and test everything one more time. Hopefully, this will give me a green coat. Now Looks like, right? Yes, we got green. So I know that was a good reflector. And if we look at code in the transactions controller, it looks a lot better. It's easier to read and to understand, and it doesn't look that bloated anymore. Okay, so we have a filter. By month, we can filter by categories. So in the next video we're going to take care off category management and the ability to add update and delete Qatar Airways. 17. 17 It Can Display All Categories: just like we did with transactions, were going to create a test to make sure that we can see all of the categories in the system. So let's start by creating a new file inside tests feature. And it's called this file view categories test I said mentioned before, I'm going to use my code snippet to create a new test class. Now, the first method we can call it can display. Oh, transactions. Sorry or categories. Now here the first thing we need. It's a category, obviously. So integrity equals these create, uh, integrity. Now that we have a integrity, we need to face it. The cattle released with this get and the euro will be activities. And here I want to assert See contiguity Name. All right, Simple enough. Let's go be the method name. Jump into the dead Amina test and fielded by that one only and see what we get. All right, we have few error. Sear actually, just one, and it's a database Ever saying that the categories has no column named. You said I d. All right, this go fix that jump to the editor and this opened the migration style. So create category stable that PHP And right here, let's say table unsigned integer You said I d Now if we do this, we probably have to modify the model factory a swell. So this open more factory And I'm going to copy the use ready definition from the transaction Mother factory and based it down here right below this love. That way, when we create a contiguity, if we don't specify use that I d by default, he would create one for us in a signed the I D to this column. Okay, let's go back to the test. You can take this test and now jump to the tear Amina in test again. Okay, First ever is fixed. Now we have a second ever saying not found http exception. And this is because you guessed it no route. So back to the editor and open routes Webb Ph beam in this at this road down here. So this will be round get categories and this should be handled in, Let's say, categories controller in the index method. So let's go back to terminal and test again. And as we anticipated categories, comptroller does not exist. So from here we can create a controller real quick. Just say artisan make controller that they would ease control it. Now we have a controller, so we contest right away and I expect this ever to be solved. But now we have another error or we anticipate another error, which is? The index matter does not exist. See Screwed top. And yet we're right. Index method does not exist, so let's go back to the editor. Let's open the categories Controller Zurich categories. Controller Then let's at a public function called index unless just leave it at that. Let's go back to the terminal in test again to see the new error, which is basically failing to assert that empty stream contains. This should be the category name, so we're very close. Now we have to do is pass all of the categories into the view. So back to the editor in this return, a view this cold these categories index and we should pass down all the categories. Here in that category is variable. Should be categories equals contiguity. Now, by solving that problem, we created a new one because now we know that the index view doesn't exist. So back to the tear Amina test again scroll to the top, and yet their view categories index was not found. So let's go ahead and create that view. This should be created in resource is views. And here we need a new folder called Categories. And inside that folder we need a new PHP file called Index the late dot PHP. Now this will solve the current problem, but we will go back to the previous one where the empty string does not contain the category name. But let's go back to the test and make sure that is the case. So back to their amino test again. And that is correct. Now we're back to the previous error, where we're not displaying the category name. So now we can focus on fixing this problem by adding content to the view back to the editor . And I'm going to borrow the structure from the Transactions index, and obviously there will be a lot of things that I don't need. But I'll take care of removing the extra stuff in a moment so GOP all back to categories index. So, like everything in based now, let's start removing things that we don't need. For example, I don't think we're going to need heading or any month related filter, so let's take that off. We do need a table now for Heather's. Let's think about what we have in categories, so we do have a date instead of a description. We have a name, and we also have a slug. We don't need the amount, and we probably won't want to leave the removed but mom as well. So let's leave that in. And for the body instead of Iterating over sections were going to eat a rate over integrity's. Now I'm going to select every instance off transaction within the form, body or within the table body. And I'm going to rename that, too. Got dignity. All right, so first column. We know it's a date, so we can say the same. Now the second color will be the name, and this name will be a link when we get to the point where we want to edit a category. So let's change this euro here. Instead of taking its different sections, we should be taken to something like integrity's and then the category 80. And for the text of the link, we will be category name. Finally, we have taken slog, so category slug, and we won't need the amount. It doesn't have any again for the removed button that we're going to need later. The action for the form should be something like a Diggory's and in captivity i d should be a delete and everything else can stay the same. These links should be something like, but they're Gordy's links because we're also going to imagine ate those and justice. More fix we have to do is, since we're calling the links method on categories, we need to go back to the categories controller. And instead of calling all we need to call, imagine eight. And that should be enough. Let's go back to the terminal and test again to see if we can get a green code this time. And, yeah, we get a green coat now. What would happen if we actually tried to go to the routes and and navigate to the categories? Least Let's give that a shot. Let's go to the city. In this navigate to categories, we actually get a decent least of all the categories in the system, But notice something. How about we look out first and then tried to navigate two categories again, we are able to see the categories without being looked in, so that's a problem. And we saw that problem with the transaction leads. But how about we try to solve it as well for the categories? But instead of doing it myself, how about we leave? These s an assignment to you and also all of these categories. I'm pretty sure they belong to a different user that the one that is currently logged in. So that's another fix we have to do. We have to make sure that the least only displace categories that belonged to the currently logged in user. So to sum up, this is your assignment. Create a test that will ensure that the least will only be displayed to logged in users and also create another test that makes sure that the least only displace categories for the currently logged in user. To do this, you can use the View Transaction Stairs class as an example. In the next video, we will go over the solution for the assignment, and also we will introduce the ability to create categories 18. 18 It Can Create Categories: in the last video, we left you with an assignment to restrict the least of the categories toe only logged in users and in that list only show categories that belonged to the currently logged in users . So let's go over the solution to those problems. Let's go to the editor and let's open the view categories test and actually, let's open the view Transactions test, and I'm going to borrow some of the code from here. For example, this test over here ensures that the list is Onley shown to logged in users. So this copy this and paste it down here changed the method name. Actually, no, it can stay the same. It allows only authenticated users. So here we signed out, then enable exception handling. And then the girl will be categories and we should be redirected to logging. So let's copy this and you know what? We should make a distinction because this is for categories and now we have two methods with the same name. So let's change these two. It allows Onley authenticated users to the categories policed, and if we're going to change this one, let's be consistent and also change the one in beauty and sections test, so it allows only authenticated users to the transactions least all right back to the view that they were this test. Let's copy this method name that's good Terminal test filter and let's see what we get. So response status Code 200 is not. I redirect code. This means that we are not redirecting. So is not authenticating to solve this. Let's go back to the editor and let's open the category school troller. And again, I'm going to borrow some code from the previous controller where we sell this problem, which would be the transactions. Control it, and I'm going to copy the constructor here a copy. Go back two categories controller, and it's based it right before the index method. And I should solve the problem back to tear Amina in testing it All right. That solves one problem now to solve the second problem, which is to show only categories that belong to you, sir. Let's go back to the editor again. And let's review how we saw that with the transactions least. So let's open the U transactions test again. And let's look for that test it only displaced in sections that belonged to the currently logged in users. So I'm going to copy again these tests from the uterine sections test and based it in the view categories. Test here and let's modify it to attack. So the method name, for example, it only displays categories that belonged to the currently logged in user. Then we create what you said that same then here, instead of in section actually going to select both East senses and renamed that two category instead of creating eight section model where you need a category model. We assigned the use that I d to the currently logged user in this one instead of Sane Order Trent section. Let's rename that, too. Oh, there, dignity and he recreate a integrity model in a sign the use of i d to these other. Use it. Then we ve siddiq take what is your ill, and you should be able to see the category description and the other category description should not be visible. Okay, that will take her test. So let's copy the method name. Let's go to terminal endless. Start testing this field and seems we have to modify the test a little bit more, and I think I know why. Let's go back to the test. And as you can see, we are using category description, which doesn't exist. So instead, we need the category name okay, back to the Ted Amina just again. And now it's telling me that he's unable to assert that the render view does not contain this category name, which means that he's explain both categories, and one of them should not be displayed now. If you remember, we saw this with a global scope that we added to the transactions model. If we open the section model and scroll to the top here, we added a global scope which will filter by user i d equals to the currently looking user . So how god we copy this entire booth method from D transaction model. So copy from here and now let's open the category model and right before the Ralph Keeney, this base, that boot miss it. And this saving method is something that we should keep because whenever we get to the point off creating the form that will allow us to create new categories, we're going to need to feel up the use ready with either the use already provided to the model or the I d of the currently logged in user. Now this step is taken care of in the tests by the Model factory. But when we get to the U I, that is something that we have to do ourselves. So let's rename these Trans section to get a body. Okay, with this in place, let's go back to the terminal in test again. And now we get a green coat. And with this out of the way, now we can focus on creating categories. So let's jump to the editor. And, as always, let's begin with test. We're going to create a new file within tests feature called Create Categories Test. I will use my code snippet to create it. It's class, and the first method should be called it Kin create cut their ways Now. This is very similar to creating a transaction. So let's open the creator and sections this and let's borrow the code for creating it section. So I'm going to copy this whole test here, and actually, I don't need a whole test well, in your it's a content so copy back to create integrity's and based again, let's just make adjustments to this coat so that it can be used for categories. For example, this variable instead of Prince Section. I'm going to find all instances in Rename It to Captivity. These should create a photography model, so integrity. So we create a new category. Then we post two categories sending the category data, and after that we should be redirected to the categories least so vagaries. And if we visit the categories, it should be able to see the category name. All right, pretty simple. So let's copy this method name and let's start testing. Okay, First error. Straightforward. We don't have a route. So back to the editor. And let's open the routes file, which is routes webbed A beach Mean, let's add a new route post categories, and we should handle this in categories. Controller Store back to Ted Amina Just again. No, it's complaining because the store matter does exist. So let's fix that. Open the categories. Controller. I had a new public function called Store and Test again. No, we respecting a redirect, but we're not getting any. So to fix this simply return. Redirect to integrity's in test again. Now it's telling me that the view does not contain the new category. So now we have to create it so to the editor. And right before redirecting, we say integrity, create with request and test again and we have a narrow Let's see, What's that about? Mass assignment exception. Okay, The name column is not mass sustainable. So back to the editor, his open the categories. Sorry, the category mojo. So right up here before the boot, let's say public fallible equals two name. We probably also need slug and the use of ideas will. That's test in. And now we get really excellent. All right, we're going to make another pass here, but in the meantime, why don't we leave you with another excitement this time? I want you to create a test that will ensure that categories cannot be created without a name. This will involve adding validation before creating the category, and obviously you always have to start with test. You can refer to the create transactions, test and used Addison, except in the next video, we will go over the solution, and also we will add the view for creating categories 19. 19 Create Categories View: So if you remember from the last video, we introduced the concept off user i d two categories to filter categories and display only those that belonged to a currently logged in users. And while everything was working in the test and everything was passing, when I came back to the budget app and they tried to access the logon page, this is what I found. And this is because while he's trying to load the general layout team, the one that has the top Heather and the links in it, it is also trying to load all of the categories to display them in a drop down link that we added. But the category stable in our life database steel doesn't have the use that i D column in it. So how do we fix this? We have to refresh our database with the updated migration files. So to do this, let's jump real quick into the terminal and to roll back and rerun all of your migration. So you have to type is artisan my great refresh. And as you can see, he rolled back everything and then recreated it once again with the updated migrations. So if we go back to the browser and now is working. But we lost the user, so we have to recreate the user once again. So let's click on register. I'm going to create this user again, which is John Doe Password will be secret. Confirm best work and register Great. We're all day again. We have a user, but if you go to all the transactions, this is going to be empty. And obviously we have no categories yet, so that would be empty as well. And this will also affect our ability to create new transactions because we can't assigned categories to them yet. So in this video, we're going to quickly go over the solution for validating the data when creating integrity's in our test and then create form or the view to allow ourselves to create categories using the U A. All right, let's jump to the editor and open the create categories test, and this is all we have from the last. I'm going to borrow some code from the creator and sections test, so let's open that up. Create sections test. The first thing I'm going to borrow is this gold from the bottom, the poster and section. We're going to need one just like that, but four categories. So copy and based it down here instead of section. Let's rename that too dignity. So the function will be called Boss Category is going to make a new contiguity with the provided overwrites. And then he's going to post that with exception handling, too. Categories you were ill and then send data and return their response to the calling method . All right, the next thing we're going to borrow is any of these tests. For validation. Let's try this one the first when you cannot create in sections without a description. Let's go pee that base that here in the middle and we're not going to create sections, we need to create categories without a name so he cannot create integrity's without a name . We're going to bullets category. We have the name Equal snow, and then a service station has errors name, and that's pretty much it. So let's copy this method name. Jump to the terminal test in future and let's get the first error, which is obviously the missing error ski from the session. So now we jump back to the editor opened the categories Controller and right before we store the new category, we're going to say this validate request and then passed Henery of rules with name being required. Let's go back to the terror me now and test again. All right, we get a green coat and that's pretty much all of the solution. All you have to do is validate the name because the slug will be created are American As of now, we're doing that in the model factory. Let's check that out here in the model factory for categories. We're creating its look based on the name but for the real thing. We're going to do this using a model event. So let's add that. Now let's open the category model and right below the use that I d. We can use the same technique saying contiguity Slug Will the either the provided category slug. Four S T R slug They stoned the category name. All right. Now we're ready to go and create the form or the view to allow ourselves to create categories in the system. So the first thing I'm going to do is I'm going to create a new file inside resource is views categories. This will be any PHP file called Create that Blade Got BHP. And since we already have a create form for 10 sections, I'm going to borrow Destructor from that. We're going to copy all of this and then baste it in categories created, baited PHP. Obviously, we need to modify some things. For example, that banner heading will be creating a technology and the form action will be cut their bodies. And we're going to use the same dry form for categories, just like we did with but in sections. We're going to use the same partial view for both the create and the update forms, which means that we have to create another partial view called categories formed a blade of PHP. So let's create that right away in the same folder categories. Let's created new PHP file called form, not blade dot PHP. And once again, let's borrow destructor from the already created in sections. Form that blade at Ph. B. So select everything copy and then paste here, and let's start modifying the structures to adjust it to categories. So the first thing we're going to need in categories is the name and That's pretty much all that. We need the name. So instead of description, I'm going to select description all of instances here and change that to name the label should also be name. And then the value should be either the old value for name or the category. Me. All right, so that's pretty much the only form feel that we need. So I'm going to the elite, everything else except for the button. And now we need a route for this form. So let's open routes wept at pH mean and creating route get categories and then category. And this should be handled in Diggory's controller on the area method. Now let's go to the controller categories Controller and down here Let's at a new public function called it, which will receive a contiguity passive permitted. And here I'm only going to return Do you categories and I made a mistake is not the end. It is the create myths that sorry go to routes and modify that as well is not Eddie. This will be created and this doesn't need a parameter, and I apologize. I was thinking about the edit form, but that's the next thing we have to do so. Instead, the route will be CA Technologies create All right back to the controller. We don't need a barometer here, So here I'm going to return the view categories create. Now let's go to the browser and test that. So if we navigate two categories, create off course, it is complaining because we don't have a category viable in the view. So back to the controller, just like we did with sections we have to create an empty category model using contiguity equals new contiguity and passed down that to the view. All right, back to the browser and refresh. All right, Cool. We have the creation form for categories if we try to use it as it is without data. Since we already tested validation, we should be redirected back and the name should be highlighted in red as it is right now. So let's try and create a new category. Let's say groceries we could save. We are redirected back to the categories. List in the category is showing. In the least. This law was created automatically for us, and everything else works fine. Now I already so that we're going to have a problem here. When we get to the update, let's see if you can guess what the problem is. But for now, I'm just going to let the problem appear, and then we're going to fix it again. This is a problem when we're trying to all the date on already created category. In fact, whether we make this a challenge, so this will be your next assignment. Go ahead and create the test for updating categories. This will include creating new class and the new test case that will ensure that we can actually update categories and to go one step further. Also created Test to make sure that you cannot update categories without a name. You can use the update transaction steps as an example, and again, I expect you to hit a bump in the road while doing this. If you cannot figure out what the problem is, don't worry, because we are going to go over solution in the next video and also we will take care of creating the update form for categories 20. 20 Update Categories View: Okay, so let's start working on updating transactions, and, as always, we're going to start with the test. First, I'm going to create a new test class within tests feature, and this will be called of the categories test again. I'm going to use my code snippet to create a test class called off the category X test, using that of his immigration straight and extending from the base. This case glass and the first method name will be it can of the cut degrees. Now I'm going to borrow some coat from the update sections test so it's open that up and let's borrow the entire content of the test and we will adjust it for categories. Copy that, paste it here and instead of section. I'm going to call this dignity and it should create. And here I'm simply doing multi selection. I know sublime supports this feature and also PHP Storm, if yours does not support it, simply replaced every instance of the world transaction inside the content of the test. Replace that with integrity. So we have one category e created and persisted on the database. Then we have a new category, which is only in memory. Then we call this foot. The euro will be integrity's. And then we passed the category idea and also the new potato data, and we should be redirected to the category is least. And if we visit the categories, least we should be able to see the new category name. Now. If you haven't spotted the problem here yet, I'm going to let the test reveal the problem so that we can fix it. I'm going to copy the method name move to the Terra meaner, distant field. Let's see the first ever. First of all, we don't have a rowdy it. That's pretty straightforward. So back to the editor, open routes with the PHP and here we're going to need a route put the u. R. L is dignities. Then we're going to need a integrity s a perimeter, and they should be handled by integrity's controller and the update method again. If we test this, we are pretty sure the next error will be the absence of the category controllers class. Sorry, The store method within the categories Controller class No, the store, the update mint. And yet we don't have an update method, So let's go ahead and create that we go to category troller and creating your public function called of date. And this will receive eight section Serena transaction a integrity. And with that let's go back to the test to a terminal in test again. And now we get the error that I was expecting. So we get a model not found exception. No query results for the model category. So what's happening here? We're trying to use in policing model binding to get a category from the database simply by passing the I d in the Ural. But if you remember, we modified the category model and told him, We don't want you to use the category i d for implicit model binding instead, you should use this luck. But now in the test, instead of passing this look, we are actually passing the i d. And that is causing the problem because he doesn't know how to look for a category using an i. D. On Lee this law. So to make this this past, we simply switch the I d. By this Look, let's go back to the terminal intestine now. The next error is that we're expecting every direction code. So let's go ahead and add that back to the troller here. I need to return. Redirect to Diggory's test again, and now he's unable to assert that the render view contains the right cut dignity name. So now we have to actually update it back to the controller in right before redirect in. We simply have to say contiguity of date into this. We simply passed the request. Oh, okay, let's just again. And now we get a green. Excellent. So we're taking care of updating the transaction. Now we have to work on the valuation, so we have to ensure we cannot update categories without name. And for this I'm going to borrow the validation from the create categories test. So I'm going to a pin create that they were ex test, and I'm going to borrow these two methods that test itself and also the post category method. So copy those. Go back to the categories, test and paste them both here. No, it's first just depose category because this will be slightly different. Instead of saying posts, we need to say off the category, and I'm going to borrow these two lines from the first test. Put them here and then borrow this foot from here to here. Copy that and replace the post. So to sum up, we're dating a category, but we need to pass the overwrites to the new category. So it's best that All right, so we created integrity. Put in database, created new one, we the overwrites, and then enable exception handling. Kali, put two categories and with the categories lock. Send a new category and return that to the color method. Now, for the test we changed. The method named to you cannot update cut their bodies without a name instead of both contiguity. We called off the integrity with the name snow and then a served. The decision has errors regarding the name. Okay, lets copy the method name in dist. And of course, we don't get any Evers, so we actually have to validate now, So let's go back to the controller and right before update. I'm going to borrow these validation from the store method. Copy that. Based it here in test again. Okay, Now we get a green coat accident, and that will be all for the solution of your assignment. Now, let's take care of the form the update for Let's Go Back to the Editor and it's creative You first. So I'm going to create a view within resources views categories and this will be a new PHP file called Off the Blade that PHP. Now this one is going to look almost exactly like the create form. So I'm going to borrow that from the categories. Creator later Beach being select everything. Copy. Then go back to the very sorry The update debate Beach being and based everything here. Now let's switch a couple of things. First of all, this will be about the category for the heading and then the action of the form should be integrity's. And then we need the category slut. So dignity slug the method will be posed, but we need to spoof a put method. So we use method field put Then we include The category is formed, but in this case, I'm going to pass down the button. Text equals two of the okay. Now we need a route So open routes with the Petri. No, we need route. Get the u A rail will be deputies and then integrity as a perimeter. And this should be handled by the categories. Controller on the Edit method. Finally, we need that method in the controller. So let's open the categories Controller and down here. Let's add another public function called it. This will receive a integrity. And here I'm simply going to return view CA Technologies and it and then past the category into the view that should do the trick. Now we need to make one final update. Let's open the view for the categories least. I think this is called Degrees Index and look for this link over here that we created before were again trying to pass an I. D. And this is not going toe work. Instead, we need to pass a slug, and this is the link that allow us to go from the least to the edit for correct. So let's go back to the browser in. Check this out. Let's refresh the categories least, and then click the name of the category. And I made a mistake with a view name. Apparently, let's go back to the editor and, yeah, I named it incorrectly. It's not update its edit, so I'm going to rename this file to edit that blade that PHP came back to, the release said and refresh. And there you go. We have the of the category form. If we try to send an update without a name, it's not going to let us. So let's changed this to food. Instead, we click update that takes his back to the category released in the category Name is updated. Okay, we're going to make another post here and leave you with one more excitement. Go ahead and implement the test for the leading categories. The U. S is already said with the removed button. But if you click on, it is going to tell you that there is no route for the lead, so that will be your task in the next video. We're going to go over the solution and then make a few enhancements to the US so that we are able to reach the creation category form from the u I. And finally, we're going to do a small re factor in the routes file. Because if you notice this file is starting to look a little bit too big. So instead I'm going to re factor these and start using something called a resource controller, which will reduce the amount of lines in this file. So that's what we're going to take care of in the next video. 21. 21 Routes Refactor: in the last video. We leave you with an assignment to create a test for removing categories, and we will go over the solution for that in just a minute. But first we have to fix a very important problem that we have right now something that I just noticed in the last video. We introduced a form that allow us to update categories, but notice what happens when we update when we have dated the name. But this love didn't get updated, so let's go ahead and fix that first. Then we will go over the solution for removing categories and then we will move on to re factoring our routes. Let's open the editor and let's look for the category model. As you can see, we are creating this look automatically right before saving the record. But we have to do this also right before updating it. So I'm going to create another event here with static off dating, and this will take a callback function that receives Deke integrity. And in here I'm simply going to copy this line from up here and paste it here, and that will update its lock right before updating the record All right, let's give that a shot. Let's go back to the browser and it's update lace category one more time. I'm just simply going to hear update, and that didn't take effect. If you want to know why, it's because lot of ill will only update the record if there is any changes to it. So if there is no change to the data on the record, he's going to save one call to the database and simply omit the update. So it's going here and this change these two utilities, maybe, and no still in effect. So let's review the code. So we receiving a category and then assign to the slug. Oh, of course, when updating this lock will always have a value. So it is not going to take any effect simply going to assigned the same value to itself. So let's remove these all together in its test. Add one more time, Click on it. Let's change it back to food, he update, and they're now it's work. With that out of the way, let's move on to the solution for the leading categories back to the editor, and let's ah, I think we're going to need a new test class, so open test feature and this create a Neil PHP file cold delete that they would eat this really categories test just to be consistent. And any borrow the code from the delete section test just going to copy this entire test from year. First of all, we need the class definition. So this class class named Leica tegra distaste extending from test case using batteries, immigrations. And here I'm going to replace this with the method it can delete instead of section slips called that categories instead of eastern section variable is renamed that to integrity, which is equal to a new integrity. So we create a new category in the database. Then we send a delete request two categories in the past in the category. This has to be cut his luck. Otherwise it's not going to find it, and then we should be redirected back to the category is least. And if we visit the categories, least we should be able to see the category name. Okay, that will be enough. So let's copy the method name and start testing. Just feel terrible this method, and as suspected, we get first ARER saying. We don't have a route for that. So let's create one open routes where the Ph. B. And we're going to need a route elite Diggory's and then passed in the integrity. And this should be handled by Diggory's controller. Sorry, that'll be integrity's controller. All right, let's this again. And the next era, we don't have a destroyed method yet, so let's at that, too. Open any school Drollet and down here that's creating your public function called Destroy, which receives a integrity test. Again, we are expecting a re director, So let's return. Redirect to categories pissed again. Now the render view does not contain or actually, it is failing to assert that the render view does not contain the category name. So now we have to delete it. So back to the controller and up here, we simply say category delete, simple as that. Just again. You should get a green coat now in there you go green coat. So as you can see, it is a very simple solution for the leading a category. Now let's go ahead and test it on the browser, going to create a new category. Right now, we don't have a link to access the creation form, so we probably will at that at the end of this video. So categories let's navigate their manually categories create this creating you went called this in its removed that just test it and no quitter result for mother at category and pretty sure why, that is. We need to go back to the editor and open the categories index view can. Right here. You see, we're pressing an idea instead of its love. We missed that fix earlier, So replace that slug. Go back to rail said Go back, refresh. And it should work. Now if you click remove now it works as suspected. Okay, with the deal, it functionality out of the way. Now we can focus on refectory. But first, let's jump into the terminal real quick and justice everything to make sure that it's still working, that nothing is broken. As soon as we get a complete green coat on all of the test, then we can worry about Harry Nico and looks like we have a bunch of errors. Let's see, what's this about? So let's scroll up to the very beginning and focus on the 1st 1 create transactions. Test it can create in sections trying to get appropriately of a non object, and this is in the index later Ph. B. Let's see if we get any indication around 9 43 All right, let's see what the problem is. Go back to the editor in this opened Eat Tran Sections Index, the plated beach beam in around 9 43 What we have easy created at. I know for a fact that's not a problem. Maybe we have a problem with the category, not giving us any relationship. So test that where we open the controller, the transactions controller and on the index method. Right after this line, let's dine dump Trinh sections, the first item of the array of the collection. Sorry, and let's dumb the category out of it, just to make sure that that is a problem. I know for a fact that when were doing tests were only going to have one record off transactions, so I'm just focusing on that one. All right, let's go back to the terminal. I'm going to copy this method name and then test and feel that only about that one, so yeah, apparently that's a problem. We're not getting the category out of the relationship and what can be causing the problem ? Let's go back to the editor. Let's review the relationship. Indeed, Trahant section model and the relationship seems to be okay. I don't see Oh, wait, I know what's going on. Yeah, of course, If you open the creator in sections test, we are creating a transaction or rather making one in memory using the these make help. Her method in that will ensure that the transaction will belong to the currently logged in user. But the category will belong to a different user because we're not specifying a category I d. Therefore in the model factory, when we are creating a section, scenes were not specifying the category I D. He will simply create one from scratch, which will in turn create a different user. And that's why we're not getting the relationship because the transaction belongs to one user. But the category belongs to another. And since we have a global scope in the category, muzzle right here when he's trying to get the results from the category disassociated with the transaction, he's also going to apply the scope and therefore giving me no results. So to fix that, we simply have to be specific about the category in the Creator and sections test. So up here I'm going to create a contiguity equals this create because I want that in the database that cut dignity and these will belong to the currently locked in user. And now, when we make that section, we specify that the integrity idea equal stew the newly created category idea back to the sections controller. Let's remove that D Brookline in test again. And now we get we All right, let's test everything again to see we have any more errors. All right? We still have a bunch, we fix one, but we still have six to go. Let's scroll to the top. And it seems we have the same problem in the of the different sections test. So let's fix that one, too. Open the of the transactions test enough here. I'm going to create a new dignity because this create dignity, and I'm only going to be specific about the category in the new transactions as the only one I care about. So integrity 18 equals integrity. I d. Okay, scope this and test again. All right, That was gone. Just everything again. And we're getting rid of every single error one by one. So now we have five scroll to the top. Same problem in this beauty in section stairs. It only displaced in a section that belonged to the currently logged in user. So let's fix that one. Okay, that's creating you. They were here. They would be Quote this, create dignity. And we only need to be specific about the category 80 in this transaction because that's the one e I'm expecting to see. So right here we have integrity equals to get dignity. I Korpi committed name back to the terminal test and feel there came that. What's fixed? This Everything again. Okay, we're forward now. We have four errors. Back to top. You can display our sections. Same problem in the same class. So let's fix that. It can display old sections. I'm going to copy these from here based it down here, creating integrity. Then be specific. Dignity. Team quotes to category. I d. Let's test this one. Just feel it there. All right, One more finished. Just everything. Direct it up. It can feel transactions by category. No query souls for the integrity mother and see What's that about? And seems like we're using the wrong create should be this create. So then the category belongs to the currently logged user. That should do drink it states that again. All right, that's old. Just everything. One more time We're slowly making progress and we just have to left so screwed up it can filter transactions by months. Casing problem. I do have a line here that can borrows a copy place from the previous test based it here and then the one I'm expecting to see is the bastard section in this case. So let's be specific about the Category 80 on that one. So let's at category I mean equals two category i. D. Korpi elements that name just a field there that insult. So that leads us with the last one. Hopefully and that one will be located in it can filter transactions by current month by default. Notice in the same class can filter sections, right? So yet same problem brutally slain from here. They said here and I'm expecting to see Korean transaction. So we specifying captivity, I think quotes to integrity. I ve all right, That would be the last one. So let's go back to terminal and test everything again. And yet everything is passing now. Perfect. So, as I mentioned for what we want to do is to re factor the routes web dot PHP file and try to take it down to a few lines instead. So we're going to use a resource controller. And the reason I have been following these naming convention, it's because lateral will enforce it. When using resource controller, he will always map the request with the appropriate method. So to do this first, I'm going to extract the only route that doesn't follow that convention completely, which is the get request to transactions with a optional category. So I'm going to take that out, put it below, and right before it, I'm going to add a route resource. And here we passed the route prefix, which in every case will be transactions. Next, we have to pass the controller name that is going to handle all of the methods in this case will be that in sections control. If now, since the convention is too much, any get requests to transactions and some parameter to the show method. We need to tell these not to implement the show method in this resource controller. So we pass 1/3 parameter, which is an array, and this array will contain a configuration called except equals show. And actually, this is an array as well. This will tell the resource controller to implement all of the methods, create edit store, all date and destroy, but not to implement this show method that will allow us to use this route down here to feel to return sections by category. Now, I'm going to comment out all of these lines and simply test everything again and make sure that I actually get a green coat just as before. So go back to the Ted Amina this everything again and we get a green coat. So that was a good re factor back to the editor. We can safely remove all of this routes here, and we can do the same with the categories. So I'm going to say route resource categories to be handled by the vagaries controller, and there are no special exceptions with this one, so we can just leave it at that going to comment this real quick and then test everything again and we still get a green card. Now we can go back to the editor and safely removed this. And as you can see with that reflector, we moved from all of those lines that we have before to simply three lines. All right, The last thing I want to do for this video is to create some you enhancements to be able to reach the create category form and also the categories least from the U. S. So for that, I'm going to move these links a little bit. What I'm going to do is to move these two links into its own drop down menu and also add a few more options in the categories throat down to both manage the categories which will take us to this category is least and also adding new contiguity. So let's go back to the editor and let's open the app that blade of PHP, which is layout file and let's start moving things around. I'm going to copy these least item, which is a drop down, and I'm going to reuse that for transactions. So I'm going to copy that based it. Before and in here I will change the drug down label to transactions and then for the items themselves. We're going to be raised this for each and I'm gonna need that. And I'm going to move these list items from up here and then baste them in here. Inside it dropped down many of you. Well, all right. Let's see how that looks. Go back to the browser into a quick refresh and we have sections drop down with ultimate sections. New transaction. And it'll be nice if we have some sort of divider between those two. So let's see back to the editor. And to add a divider between those two. Simply a a new list item off glass divider and also with row separator. Okay, let's check that out fresh again. And now we have a nice divider between the two items that exclude. All right? No, I want to do the same with categories. I should have a link here saying or categories and also another link for a new category. So let's do that right before the for each. I'm going to add another list item with a link to the categories least so that would be integrity's. And for the label, it's a manage categories and then another one that will lead me to categories create and for the label create category or actually, new category. Just be consistent with the wording. Because we're saying new transaction of here, I would say nuke integrity down here. And now let's add a divider between the category least and these two items. So I'm gonna copy this the writer from here, and paste it here. All right, let's check that out. Quick, Fresh and the categories Drug DOWNAL has a couple of new items, one for manage categories. Which leads me to this view right here in another one for new category, which takes me to the new category or the creator they would form. We also have a list of all of the categories which will take me to the transactions least in filter by that category. All right, I think that will be all for this video. We have done a lot, So why don't we take a break here in the next video? We will move on to budgets. We will create a test for viewing, creating off dating and the leading budgets. And from there we move on to the main budgets view 22. 22 It Can Display Budgets: in this application, we can create monthly budgets for any given category, like $200 for food or $300 for a car maintenance, for example. So basically, a budget is nothing more than a record that belongs to a category E and has a certain amount of money for a specific month. Let's add a test for this, starting with the ability to show budgets for the current month, I should be able to see budget category and the amount. So let's add a new class. Let's hop into the editor and let's create a new class inside tests feature. It's called This view budgets test. I will use my code snippet to create the entire class again. This is just a basic class called EU budgets test extending from that's case using that abates migration straight in the first method will be called. It should display budgets for the current month by default. First, I will need to create a new budget for the current month. So let's say, But Jet for this month equals two This create hap budget, and I am fully aware that the budget class doesn't exist yet, but again it is a nice practice to just write the code that you wish you had and then have the test. Tell you what you need to add, go at it and then made this pass. So I'm just going to write this in a wishful manner. Now let's create a budget for the last month. So budget for last month equals two. This create at budget and we specify the creation date so created at or actually, no, we're going to need a different column for the budget date because we could create a budget today. But that budget will be for, say, the next month or two months in advance. So let's say this class has a budget date this weekend. A sane carbon now and then sub month in that will substructure one month from the current date. Okay, now, if I visit the budget least with this get, let's say the u. R L is budgets I should be able to see so assert see budget for this month amount, and I will also like to be able to see not only the amount but also the balance off the budget, which is basically the total amount of the budget minus the some off all of the transactions for that specific category. So let's say we see budget for this month and let's pretend this has a function called balance. I'm going to copy these two lines because I should be able to not see. So assert. Don't seem the budget for last month amount in a certain don't see the budget for last month violence. Now one peculiarity that I found while I was developing this project is that this, too, will give me interjects and for some recently assert, See only likes to deal with strings. So the solution that I found was to simply typecast the result into a string. If you know a better solution, feel free to share it in the common section. So I'm going to cut this and added to all of the assertions. So with this, we can start testing, so let's copy the method name. Go back to the terminal test and filter by that method name Onley in. Let's see what we get. And the first error is that we are unable to locate a factory with the name up budget, so we need a more factory in for a motor factory. We need a model, so let's start by creating that So artisan make model budget. Now let's go back to the editor opened the model factory file again. If you don't remember, this file is located inside database factories, and at the end, let's at factory define budget. We don't need the slash it beginning like that class, and then we pass it. Call a function. We faker generator again. We can amid this first lash, call this faker and let's think for a moment what we need for the moral factory. First of all, as we said, every budget has a category so that we can later have a balance using all of the transactions for that giving category. So let's start with cut dignity, I d. It is a sequence to, and we can borrow this definition from up here, which will be a function that returns the result of creating another category using it's model factory. We also know that every budget will belong to a user, so let's at a user ideas. Well, I'm going to borrow it from the previous model factory. We also know that we need an amount for the budget. So let's say amount and we can assign these faker Arrendel Float will do with two decimals between 501,000. And finally, as we mentioned before, we're going to need the budget date so budget date and we can default this to carbon. No, we don't need to have the balance as a column. The Darabi is because the balance is actually a calculated value. All right, so we have the model and we have them or factory. Let's go back in test again. Now it is complaining because we don't have a budget stable in the data Aries. So it's time to create a migration for the budget stable. And we can do that from here. Typing artisan make migration. It's called his immigration Create budgets table, and let's add the create option to create a table cold budgets. Okay, let's jump back to the editor and added that migration final is opening up. Create a budget stable. All of your migrations are located inside the database Migrations folder. We can leave the I D as it is, and let's start adding some more columns. For example, table unsigned integer for the category ating another unsigned integer for the use of riding. We will need a float for the amount and finally a time stamp for the budget date. Okay, now we have a table. This Disick it next is complaining because we don't have a route. So let's go ahead. And at that open routes wind up Ph. Bean and to follow the same methodology as we have been doing with categories entrance actions. We are also going to use a resource controller for budgets. So let's at route resource with a you Ariel off budgets and they should be handled by the budgets controller. Let's test again. Now it's telling us that the controller doesn't exist. So let's create that from here in whatever has a handy method for creating resource controllers by typing artisan, make control it budgets controller and we add the resource option. Now, if we go back to the editor and open the budgets controller, you can see that lateral scaffolds. All of the methods for you starting with index, the create store. We're not gonna need this show method, so we can pretty much delete it. Then we have edit, update and destroy. If you remember previous test we had to add every single method one by one. But here lot of it already did that for us. Okay, lets test again. Now it's telling me that it's failing to assert that empty string contains 9 46.67 which is the amount. So at this point, we're going to need a view so back to the editor. And let's create a new view file Inside Resources, the youth here I want to create a new folder called Budgets. And inside that folder we need a new PHP file called Index That Blade, not BHP. I'm going to borrow some HTML code from any of the previously created index files. In this case, we can use a category. For example, categories indexed a greater pH. Me. Let's copy everything basted inside Budgets index tabulated Ph. Me and let's start more define it for budgets. And actually, I'd rather copy everything from the transactions because we're going to have a filtering functionality by month so that one already has one. So let's open different sections. Index, copy everything and paste it inside. Budgets index that blade PHP. All right, so at the beginning, we have our months filter drop down so that states Same. But let's at a title to this view. How about maybe a deeps cool and the four and gives four Call wife dif? And here we can have an H four title. And let's say that says monthly budget. Now, since we have something that is four column, why that the beginning? This will be a line to the left. We have to take those four columns off of the upset so that it will not overflow. Now, down here, we're going to need a goody an amount and then also the balance and finally a remove button as well so we can live it with only for columns. I'm going to delete the first column because the first column here will actually be a link when we have to add it a budget. So this will probably take me to something like budgets, and I'm going to rename section everywhere with budget. Okay, so this will take me to budgets. Margit. I d at it. And since this is the category column, we probably need to display the budget category name. This will later be a belongs to relationship between the budget in the category. Next, we're going to need the budget amount and finally the budget balance. So we called the pretend function balance that we will add later, and the removed button will take us to budgets, budget I d. Method post. Then we have a method field for the delete CSR if field and the button that can stay all the same. And I forgot to rename this from thin sections to budgets. I don't think I'm going to need to Pagine eight this view, so I'm going to remove these for now. All right, that should be enough. So I expect to see a few Evers here because for Temple, we don't have a current month for this view. We don't have a balance function yet inside model, So let's test again and see whatever we get. First of all, we're not rendering the view yet. We created it, but we didn't modify anything on the controller, So let's do that. Opened the budgets controller in from the index method. Let's return a view called Budgets Index. Now, how about we get ahead of ourselves a little bit and at that current month variable, we can get that from the transactions controller. Just copy this line and based it over here and now passed that down to the view. And since we also know that we need the budget least, let's create that right away with budgets equals two budget in past that down to the view as well. So we are getting ahead of a few errors in saving us a few minutes. Correct that. See what happens if we test again. Screwed it up. Seems like we forgot to include the carbon class in our controller. That's easily fixable. I dependency up here in testing it. Okay, another error. Trying to get a property off non object. And this has to do with the fact that we are trying to access the category relationship from the model, but we still don't have any. So let's open the budget model and it's at that relationship. So we need a public, a function called category, which returns. This belongs to category and for KIIS category. I d. All right, let's see how that looks test again and we get same ever and let's see if you can guess why this is happening. We face this issue before exactly at the same point. We were trying to access the category in a relationship with a transaction, and this is because we're creating a category that belongs to a different user. So let's go back to the editor hoping the view budgets test. Let's create a category with this. Create, uh, dignity. And it specified that over here that they would get Dean equals two integrity. Let's have that down here as well. All right, let's this again scroll to the it up. And now we have a different error saying the balance method. It's undefined. So now we need to create that balance method on the model. But for that, I'm going to do like an inside loop and create a unit test for that method Only once that it's passing, I will bubble back to my feature test in tested again. So for that I'm going to create a new class or new file inside Fists unit, and this file will be called Budget Test. The screen tired this class in this first method, let's call it it has a balance. So to set this up first, I'm going to need a category which will be equals to these create at category, then I'm going to need a few transactions, so sections equals to these create happen section. We specify the Category 18 and let's say we create three of those just so we can have something to sum up. Finally, we create a budget with this same category. Now the expected balance. It's equal to the budget amount, minus the some of the amount off all of the transactions. We can do that easily with transactions, which is a collection, and a collection has a some method to which we pass a column that we want to use for the some, which is an amount. So this will give me some off all of the values inside the amount for that collection. Finally, we say this assert equals the expected balance, and we compare that to budget ballots. So all we're doing here, it's simply set up our test with the necessary data, calculate the expected value that we need and then compare that the results off calling violence method which doesn't exist yet and those two must be equal. So with that, let's copy the method name and test test in future, and we get the expected error. The violence method he's undefined. Now it's time to go and add that method to the model. Open the budget model. Let's add a public function called balance, and here we simply return the result off the amount for these budget minus and here we're going to access a couple of relationships. First, we're going to refer to this budgets category, and then we're going toe access all of the transactions associated to that category using another relationship called transactions. This is a has many relationship from category to transactions and then from the resulting collection simply some. The Amount column. These relationship doesn't exist yet, but we are going to let the test let us know that. So let's go back test. We're calling the member function some on no, and that is because again, the transactions relationship on category doesn't exist yet. So let's open category model and down here, let's at a public function cold sections and this will return. This has many transaction class and the foreign I D will be category I d. Okay, let's going test again. And now we get a green coat. Excellent. So we make sure that the result of the balance. It's accurate. Now we can circle back to the feature test and test it again. We were testing it should display budgets for the current months by default. And as you can see, we moved up to another error. And this is because we are not filtering by the current month, so he's failing to. A certain page does not contain the amount for the last months, but so let's go ahead and fix that. This opened the budgets controller, and here we can use the same technique that we use with transactions so we can probably open the transactions, control it, and let's copy these few lines from here and paste them right after the current month. Let's remove this line from here, and since we are not going to Pagine eight, we can simply say budgets equals two and replace this with budget and let's use a scope as well called by month. And I'm going to copy this and paste it down here, replacing this line like that finally, at the end of this too. This will be useless if we didn't call the get method. Otherwise, instead of a collection, we will be receiving a query builder. I expect to see an error saying that we don't have the scope, but let's go ahead and test first scroll up And yet we don't have a by month scope. So let's fix that. This opened the budget model again, and actually, we can borrow this logic from Deterrent Section model. So open section model. Let's copy this by month scope direly copy from here based it down here. But as we mentioned, we are not going to filter by the created at column. Instead, we filter by the budget date. Come. Can't miss this again, and we have another error. We forgot to include the carbon library in the model here. We're using it, but we didn't include the use statement up above. So we simply at au statement here and test again. And now we get a green coat accident. All right, let's take a break here in the next video. We're going to cover the tests for adding budgets, but let's leave you with another assignment. Why don't you create a test that will ensure that the budget least is only displayed for logged in users? All right, I hope you have fun with the assignment, and we will go over the solution in the next video 23. 23 It Can Create Budgets: Let's go over the solution for showing the budget lease on Lee to logged in users. We already sold these with the transactions, so we're going to borrow the code from there. Let's hope in the view transactions test. And here we have a method called it allows only authenticated users to the transactions least. So let's copy that and paste it right up here. Let's change the method name instead of different sections. We're going to replace that word with budgets. So we sign out, enable exception handling. We see the budgets, you are ill, and then we should be redirected. Toe the log in page. All right, copy this method name back to the terminal test and filter by this one only and see what we get. Okay, It's telling me that we are respecting a redirect status code, but instead we are receiving a response status code 200. So it's fixed this. Let's open the budgets controller and at the top, this at a constructor. And here we simply say, this middleware out, which will protect the entire controller without indication. Okay, let's go with hand test again. And now we get a green coat. Very simple. Now we can move on to creating budgets for these. We're going to need a new class. So inside Tests feature is creating a new file cold, create budgets dist. And here I'm going to use my code snippet to created this glass, which will be a class called Create Budgets Test, which extends from test case in uses database migrations in the first method, we already cover these with transaction so we can borrow. The code from there has open created in sections. Dist. I'm going to borrow this entire method. It can create sections GOP and then bass that here replacing this instead of transactions. Let's replace this world everywhere with budgets. So let's review We're going to need a category e belonging to the currently look user and we're going to need a budget. So it's replaced transaction with budget, which is equal. Sue this make at budget assigned the category I D. And then we posed to the budgets. You are l sand the new budget data and we should be redirected to the budgets euro. And if we visit that you are ill again, we should be able to see the budget in this case, we don't have a Scripture. Instead, let's go with amount. And again, this method doesn't work really well with numbers. So let's typecast this to a string. Okay, this should be enough to start testing the scope of the method name back to the terminal test and filter by this method, and let's see what we get. We are respecting any redirect status code, but instead we're getting a 200 response that scope. So let's fix this. Open the budgets controller and look for the store method. We're not going to need this request parameter, so let's get rid of it. And also, let's update this PHP their comment. And here, let's return. Redirect to the budgets you Earl. All right, miss this again. Now it's telling me that the render view does not contain the budget amount, so it's time to actually create one. And we can do this right over here saying budget create and then passed all of the request request full. And let's test it. We have a new error. In this case. It's telling me that we have a mass assignment exception on the category I D Field. So to fix this, let's open the budget moral class and up here. Let's at a public feel, herbal, equal stew, category, ivy and in advance. I know that I will also need the amount and also the budget date. This will save me some time with tests. Okay, lets test again. Let's see what the ever is in this case. It's telling me that the budgets use that I d feel cannot be. No. And we already had this problem with sections, So we're going to solve it in a similar way. Let's open the transaction model class, and from here I'm going to borrow this entire public static function boot method. So copy back to Budget and Basit here. Mellis replace it there in section viable with budget, and this would be equal to budget. You said I D or the currently logged in user. And here I'm killing two birds with one stone because I am also making sure that I will always filter the budgets by the currently logged in user. And in fact, in a little while, we're going to have the test to make sure that this actually works. But let's keep focusing on the problem at hand. Let's go back in test again and now we get a green coat. Okay, now let's at that test that will ensure that we only display budgets that belonged to the currently logged in user. And we're going to borrow that test from the view transactions. This class Seoul is open butor and sections this class and let's look for this method it only displaced in sections that belong to the currently locked in user. I'm going to borrow this GOP in this open the view budgets test, and that's based it down here. Now let's make some modifications. For example, I'm going to replace the word transactions with budgets. We will need a category. We also need a different user, and we're going to need a budget. So let's replace a viable name with budget and we assign the use that I d. And in fact, we don't have to be specific about that. We can simply use our own rapper this create which will take care of this part here. We only have to specify the category 80 which makes me think that a place I borrow this coat from should have the same modification. But let's do that in a moment now for the other in this case, not other turn section. It's actually or their budget. And we also need to change this to budget. So for the other budget, we also need to specify the category ating. So let's make those both in the same captivity. So we have a set up ready, Then we visit the budgets. Your l and we don't have a description. So it's changed peace with amount and make sure that we take ass this to a string. All right, that should be enough. So let's go ahead and copy this method name and tested now, since we already had the code in place. When we copy and pasted the put method for the model class, we immediately get a green coat. So that saved us some time. All right, we're going to take a break here, but leave you with an assignment. Go ahead and create all of the tests that will ensure that you cannot create a budget without a Category 80 an amount for a budget date. Also, for extra credits, why don't you also create a test that will ensure that you can update budgets and after that at the test that will ensure that you cannot update budgets without a category I d. An amount in a budget date. In the next video, we will go over the solution for all of that and then move on to the leading budgets. 24. 24 Create and Update Budgets View: Let's work on the create form view for budgets. This will be very similar to the one we use with transactions. Let's go be that one and then modify to our needs. It's open. Resource is views transactions. Let's copy the create that bladed PHP, and we're also going to need the form partial view. So let's copy that as well. So copy and then opened budget solder and paste it here. Let's start with the creative. First of all, we modified heading instead. Creator and section it say create budget in these shoot post too budgets and we're going to include budgets for now, this. Open that for impartial view and let's start moving things around. For example, the category drove down. That's here. Let's move it a buff. So I'm going to cut in. Let's put it right of ah amount, and we're not going to need a description in this case. So let's remove that next. I'm going to need a drop down for selecting the budget date, so I'm going to base that off thes drop down from here, so I'm gonna copy that one in, pasted below the amount, and I'm going to call it budget date. So let's replaced category i d. All off the instances and replace it with budget Date the label Will the budget date select name, Budget date. One empty option. And here, instead of iterating over categories, I'm going to pass an array of months. So for each months as month in this case, the value for the option will be months. And if the month it's equal to let's pretend that budget has a method for getting the month to get months, then that option will be selected. Otherwise it won't be. And here again, we just need to display the month. Next, we needs to replace the Stern section Viable Queen. But all right, I think that's so for the view. Let's move on to the controller. We know that we have to pass down a few variables. For example, we need a least of integrity's. We need a budget viable and finally a least of months. So let's open the budgets controller. Let's look for the create method and let's see first, let's create an array off month names in a three letter format. So, like this going from January up until December, seems this is the creative you. We only need a budget equals two the new budget. So there's an empty budget viable and then the integrity's equals two categories. Integrity. Sorry. Oh, finally, turn view, budgets create and then passed All of the variables. We come back months, CA Technologies and but okay, we're done with the view The controller. Finally, we need the route. So let's open routes. Webb, PH. Bean And no, actually, since we use the resource controller, the route is already created for us. So this test is in de browse it. We looking to her application and navigate to budgets create, and I forgot to add the get month to the budget model. So let's do that. Let's open the budget model here I billowed. Balance. Let's create a new public function cold get months and here I will return. Well, I have to make a decision if we have a month. So if it said this budget date, then we return carbon parse, which would bars a date. And when we're going to parse, is this but date and then return that in a three letter format. Otherwise we return No. Okay, let's try that out in the browser again. And there you have it. We have the categories. We'll have one right now. The amount in the budget date, which goes from January to December. All right, let's trying create one food. Maybe it's all OK. $200 for food and it's make this for the month off. November if I save, uh oh, looks like I forgot to create a budget stable or rather, rerun the migrations to create the stable. Let's do that real quick, Miss. Jump back to terminal And here we type artisan, my great refresh. And this obviously means that we lost all of the data that had. So I have to create any user and maybe create a couple of categories. So I'm going to do that on my own postive 80 for a moment and then come back when I'm done . Okay, Now I've created Fuca. Integrity's in. Obviously, I created a new user and logged in with it, so lets navigate again to budgets create. Give this another shot. Food. $200 November and looks like we have an interesting error here. We're trying to insert the value. No, which is November into the column budget day, but that is not a value date. Time value. So this seems like we were not testing properly because this air should have shown up, and instead we got a ring status in the last video. So let's go and see what's happening in the model class in nothing wrong. Here. Let's go back to the test to see what we're doing. Create budgets test. So he recreated integrity and then make budget out of, ah, model factory. Maybe the problem is there, so factory and we look for the budget and yeah, in reality, we're not actually passing a carbon. Instance, we are passing a three letter months into the request when we are actually trying to create a budget. So this is no reflecting what the application actually is doing. So this test is incorrect. To make it correct, we would have to form a this as a three letter months, and then we will have to test it again and probably will see the same back to tear Amina testing field there. And yet now it's failing. So let's go ahead and fix this, and we can do this inside the budget model. So let's open budget and right here in the saving event, I'm going to transform the input, which is a three letter month into an actual carbon instance. So budget budget date equals two carbon parse budget budget date and then former that as a daytime strength. So we can simply say to daytime string, Let's test again when we still have a nearer, etc. Well to purse time Stream Looks like the Budget Day doesn't have a good time string, so let's do some debugging. Well, it's dying. Dump budget, budget date sister again to see their value. 44. That's interesting. I think I made him a stay with the format in the model factory, so let's go and check that out. First, I'm going to remove this line and then go back to more factory Carbon. No, is not double you. It'll be m. So, yeah, that was a wrong format. Let's test it again. And now it's passing. Okay, let's go back to the browser and give these another trade. We're going to refresh, which will resubmit my requests from earlier. And there you go. Now I have a monthly budget for food of $200 in the balance. In fact, if we go and create a nutrient section, let's call it groceries for, let's say, $50 in the food category. Didn't say that if we navigate to the budgets again, you can see that the balance now says 150 because we already spend $50 out of the 200. We are located for the monthly budget. All right, we're very close to finishing a product. So now we have to create a form to update our budgets. So let's go back to the El Authority. Should be pretty quick. Let's go ahead and copy this edit view out of the trance sections for the and based it inside budgets, open it and thats modified to our needs again instead of section. It's called his budget. We're going to post two budgets Budget I D. And then include budgets, form and change. It takes a button to on the now This should be working out of the box because, remember, we already have a route. Since we use resources controller, I think all we have to cover now it's the controller message. So let's go back to the budgets controller. This copy this three lines from here and paste them inside the edit method except the budget. We're not going to need that because we will receive that from implicit model binding. So budget budget. Let's modify this speech, be duck comment and finally return for you. Budgets Edit Let's pass it months categories in budget. All right, let's give it out of train. If we click on this one, we should go to the edit form. And yet there you go. Everything is filled up. So let's modify instead of 200. Let's make it 275. And, as you can see, it is working off the box. That was really quick. The balance is still working, and now I think all we need to do is remove it. Yet everything is working, so we have our monthly budget view. So all we have to do now it's at a little bit of enhancements to the U Y. For example, I would like to be able to navigate to the budget least right now, we don't have any means to do that, and maybe we could do that by just squeaking on this budget banner here on the branding name and we could also add another link here, in between the branding and in sections so that we can navigate to the new budget for. So let's go back to the editor and finish this up. Let's open the layer of you, which is tap the later pH being located in resources, views, layouts. And let's look for that branding right here. Branding image currently goes to home. This change that to budgets and right here in the nut bar before the transactions dropped down. It's at an L. I. And it's at a link two budgets create in the label should be new, but all right, let's see how that looks. Let's navigate toe sections. There it is. Now, if we click on budget, we go to the budget least any quickly. Call new budget we navigate to the new budget for 25. 25 Query Optimization: In this last video, we are going to introduce a very, very helpful to called Lauraville debug bar. I will leave you a link to the package in the resources section of this video. But for now, let's follow up the instructions together. I'm going to scroll down to the installation part. And as you can see, we use composer to install the package. So I'm going to copy this line from here and then paste it on my terminal. I'm already inside my project folder and remember to use version 2.4, which is the one that is compatible with level 5.4. So I'm gonna hit, enter and just let it in style. It may take a while, so I'm gonna pause this video and come back when you step. Okay? The package has been installed. Now, the next step in the installation process will be to open the convict at the Ph. B. And at this to the rate off service providers. So I'm going to copy this jump to the editor and this open conflict after Ph. Bean and scroll down to the array of service providers, which is this one. And it's at the new service provider at the end right about here. Next, we're going to bringing the package configuration file to our local configuration folder using this line from here. So I'm gonna copy that. Jump back to the Ted Amina paste at and then he entered, and it created a new configuration file Inside Conflict in the finest called debug bar. The PHP. Let's see what we got inside a file, this open debug bar that PHP. And we have an enabled setting that is coming from the dot e and B file. It has some settings for storage by the fold. It's enable using a file driver, and it's throwing everything in the storage folder. We also have a setting for connection, which is nobody's fault and one for the provider, which is and then we have some Ajax configuration by the fold. This is very cool. Even if your application has a jack schools, the debug bar will catch those requests and update the information on the bar automatically , so you will get, for example, all of the queries that were executed when an Ajax call to the server. But for now, let's just jump back in our application and see the debug bar. It should come up down here by simply refreshing the page. And there you go. Now we have a bar down here with a lot of information of our application queries. Exceptions views how much memory it's using. How long did it take load, etcetera? And the thing I use the most is the square is section here. If you click on it, you can see all of the queries that were made while our application was running. And here's where you can start sporting some problems. For example, you see this select star from categories and then transactions. He's doing this a lot, and thes repetition of queries is a problem called in plus one, and this will be most apparent in the transactions. I think Let me navigate to the in sections, all transactions. And before this video, I went ahead and created a bunch of transactions here so that you can see this problem even though we have 12345 records, you can see that we're actually executing nine queries total, and if you open it for the details, you can see that he's selecting from categories a lot like 12345 five times in total. And this because for every transaction Real were displaying were lazy loading the category , which is a relationship off the transaction model. So here we're going to solve that by eager loading the category and therefore reducing the amount of queries their application. Thus, let's turn back to the editor and it's open the transactions index, the blade of PHP. I'm going to show you where the problem is, and then I'm going to show you how to solve it right here. For every transaction, we are displaying the category name. So if we open the transaction model, we can see that category. It's a belongs to relationship between transaction and category. So literal handles relationships in, ah, Lacey loading way, which means that it doesn't really makes a query for the category. Until we requested in Nairobi for every single transaction in the collection that we're explain now we're going to solve this by eager loading the category information right away , and the purse expert to do this is in the Global Scope section because this will be executed for every single query that we make to the transaction stable. So as well as filtering by the user, i d. We can also add one more call here called With There with Method will receive the name off the relationship that we want to eager load in this case category. If we had more relationships that we want to eager load, you can also pass days as an array off relationship names. But right now we only have one, so these won't be necessary. All right, with this small change, let's go back to our application and let's see how many queries we execute now. We are currently at nine queries, but if we refresh now, we're executing only five queries. Let's analyze those. We have one query to get the user i d. From session. We also have another query related to imagination than the next to queries I related to the transactions. This one will get me the least of all the transactions that we're looking for for the current month, and the next one will get me all of the categories for those transactions. All right, so we solve this problem in the transactions view. Now it's time to solve it. In the budgets view Let's jump back to the editor. Let's open the budget model. And as you can see, we also have a category for the budget. So let's eager. Load that in the global scope section by calling with category. And now let's go back to the browser and let's see those square ease Reduce were at 12 right now. But if we refresh it goes down to 10. Let's analyze those again. We have the use of for the station. Then we have all of the budgets. We have the categories for those budgets, and then we have two sections, but we're still repeating thes query categories. Transactions Category. Eastern Sections Category. Eastern sections We should result this and I think this has to do with the balance that we're calculating here for every single row in the budgets collection. So let's go to the editor and down here in the violence method, we're calling this balance for every single row in the budgets collection, which is also access in the transactions in the category. So too eager load the transactions in the category, which we are already eager loading here. We can simply at a dot so that we can eager load. Not just a category, but also the transactions for that category. Think of it as a nested, eager loading. So let's go back to the browser and refresh. We are at 10 queries right now, and that goes down to six. Excellent. So with that, we have made some optimization. Is toe the queries in our application and improving performance in the process. Thank you very much for watching, and I'll see you in the next one.