 Hey everybody, this is Brian. Welcome to the third video with Ye2. Today we're going to be really going over CRUD. So first thing you want to do is bring up your website if you haven't already and then we're going to go to a route which is the question mark equal. Oops, question mark, yeah. Equal GEE. That's GII. That'll bring you to the code generator. And once again it's a magical tool that will write all the code for you. So we're just going to bring up our little, I have some code of something else that I'm working on here. Sorry about that. Get a little organized maybe. Pet store, where are you? There we are. So we've got this code that we've been working on here. And thus far everything's been auto-generated and that's not going to change for this tutorial. We're going to generate some stuff for this as well. So we can just see that you know we only have our site controller but we've already generated the models from the previous tutorial. So what we're going to do now is generate what's called CRUD which stands for create, read, update, and delete. Basically it's just a bunch of views and a controller that allow you to well create, read, update, and delete. So we're just going to go ahead and click start under CRUD. And if you've used the Ye1 this will be a little confusing because you have to actually do the fully qualified path to wherever you want to put this thing. So the model class, what do we want to do here? Let's bring up our database. We want to, let's make a pets. Let's do that. We're going to take this pets table. We're going to make some CRUD for it. Actually, you know what? No we're not. We're going to do accounts first because we've got our column constraint. Oh no we don't. All right. Well we'll do pets. I like pets. Why not? So we're going to do app models. Now whenever you have a question just mouse over the label here and it will tell you exactly what it's looking for. Now a search model that's different than a model. A search model allows you to, well, search. It sounds a little confusing and it is. The reason why you need a search model is because a model is a representation of the data. And if you're going to search you're actually going to perform a filter. So you're changing the representation of that data. So we're going to do pretty much the same app models and then we're going to say pets search. Now the controller class, we need to actually generate a controller. So we're going to do app slash controllers and then whatever the name is controller. You should know you should call this a controller. Don't just call it pets, call it pets controller or it'll get kind of cranky towards you. All right we're going to go ahead and hit preview at this point. And if you get an error just you know figure out what it's telling you. Nine times out of ten you don't have the right path or you have a naming convention incorrect. Notice how we didn't have to fill in the view path it just automatically knows. But if you wanted a different location this is where you would change it. And it's going to give you a preview of everything it's going to create. Notice how we're creating a controller, we're creating model, the pets search, the pets model already exists. And then we're creating some views here. We're going to go ahead and hit generate. Tada! Now unlike yee version one this does not give you a nice pretty little link for you to click on to preview it. It's just the code was generated. And I think I said this in the previous tutorial. Sometimes you'll click that and it'll say generating. But you won't actually have a file. And so it's always good to go out and check. There's our pets search. And when we go to views we should now see yes there's pets. And there's our views. And there's our pets controller. And we're going to go through those files real quick. But first we're going to actually bring up what we just created. You can change the route to pets. And voila, there's pets. Now when you do not include a view, like if we click on create you see how it's pets slash create that percent to F is the HTML encoding for the slash. When you don't include that it just goes to index by default. So let's go back and this is called a bread crumb at the top. You can see how all of this was generated for us. So we've already got some pets in here. We can create and from over in this little area we can view, we can edit and we can delete. So we can actually let's just say type MIT and hit enter and there's mittens. That's the search class in action. The reason why you need that search class once again is because you're changing the representation of that data. So we can actually go in here and let's create one. Why not? I'll see category. I don't remember the category names. We're just going to say one. Test animal. Why not? Cost. Let's say this is a really expensive animal. We're going to leave the picture blank and we're going to try and create this. Notice how because we didn't put the data in there it's saying date posted cannot be blank. That's part of intrinsically with the classes. We're going to look at the model class and explain that a little more in depth. But that right there is actually an action and that's why you use crud because it takes all that code out. You think about that. You would have to write the code to show the form to talk to the database to verify the input data to do all these things and it just makes life very, very simple. So let's just grab a date here just because I really don't feel like typing that out. I'm pretty lazy when it comes to that stuff and we have created an animal. Now we can either update or delete. Pretty simple. If we go to update just brings us back to this editor and if we delete it says are you sure you want to do this? I'm going to hit cancel because I really don't want to delete my test animal but it will actually delete it. Same thing here. You can click on view which brings you there. You can click on edit. I mean it's pretty self-explanatory. Notice how the breadcrumbs auto update. So that is crud in a nutshell but now we're going to deep dive into the code. So let's flip over and we are going to look at the pets model first. Maybe if I can quit being retarded here. There we go pets. This is the main pets model. This is an active record meaning it talks to the database and some of these things may be new to you. You see these properties? That's how we tell this is a specific property. Sounds self-explanatory I know but you need to have those in place and it's all auto-generated for you and if you don't have those bad things will happen. You won't be able to access it. Now this right here is a special property. See that's id category 0. Let's flip over to the database real quick. Remember how we did this foreign key? This actually points to the index in the category table. So what ye does, let's flip back here, is it creates a special property based off whatever the name is and that actually will do what's called a lazy load on that record meaning if you say pet, that would help if I actually did this right, pet and then you do a point or two, the id category. I'm going to copy and paste because I'm lazy. It'll actually load that record from the database automatically and then you can say name like that. So you don't actually have to do a full SQL query to pull that up. Pretty neat huh? Now if we look at this you can see how we have our table name which is pets but then we have this rules. What is this? Well this tells the framework what each property really is. You can see how they're required. That's why date posted said it can't be blank because it's required. However you notice how picture is not required which is why we could get away with not putting a picture in there. We're saying id categories and integer descriptions of string and you can get you know a little more interesting here. You can say like name and pictures of string with a maximum length of 255. All that's auto generated for you. You don't have to mess with it although you surely can. I do on occasion. Date posted is safe. What does safe mean? That means it's marked for safe search so that when you're searching it'll automatically try to convert it. At least that's how I understood it. If I'm wrong somebody let me know. Attribute labels. This takes the column name and breaks it into a friendly name for the view. So you can see like id pets is now id space pets and id category is now id space category. So if we go to the actual page here you can see the id space pets id space category. So if you don't want to see the id you can actually just you know change that to pet number. So when we just kind of update this you can see it's now pet number and same thing when you go to edit it here which you won't actually see it because it does not going to let you edit the pet number. So maybe that was a poor example but I think you get what I'm saying here. You can update those attributes and the labels will update with them. And right here is your special reference too. You can see how it has the git id category zero. Ignore the git part. What this is really called is lowercase instead of upper id category zero. That's really all you need to pay attention to and what it'll do here in the background is when you call that it calls this function automatically which this has one and then it does the linking for you. So that in a nutshell is the pets class. Now we're going to look at the pets search class. Notice how the pet search extends pets. So it's basically the pets class we just looked at but it's extended. We're inheriting it. And then we do a couple different things. We add in some more rules. We do a scenario which we're not really going to get into scenarios too much but basically you can say my scenario is I'm editing or my scenario is I'm purchasing or my scenario is I'm selling you know you have different scenarios and it can make it very complex. We're going to keep it simple for this discussion. But right here is the real magic search. When you're in this guy right here and you type in say test that's what is being called when you hit enter is that right there. It's the search function in the search class and it'll give you prams and you can actually you know put those out in debug and let's actually talk about that real quick. Let's say ye, warning, and prams. I'm not sure if it'll let us do this but we'll try it. What we're going to do here is we're going to create what's called a debug message and we're going to go back out here. We're going to just go boom and you see how that little one is now orange. This is called the debug bar and it tells you a lot of information like the version of ye, the version of PHP, the status return, the HTTP status, the route you're on, the log, the time it took to load, the amount of memory, the database transactions, and the time and the asset bundles. So if you click on log here is your log messages. Now the reason why I did a warning is because it'll stand out a little better. You can see there's our warning and these are the prams. It's an array. So you can add pretty much anything you want in here and you can see everything that happens right down to the SQL queries that ye is generating for you. It makes things a lot easier. So when you're in their troubleshooting you can say like ye info, performing a search. Save that. We'll run it again. Notice how it doesn't increment for the infos only for the warnings. So you should use your warnings sparingly but your info is in there. So that's a good way to give yourself like little debug notices. When you actually upload this to a public site, something other than local host, that will not be displayed. It automatically disappears. It's pretty slick. I like it. It makes things a lot easier to debug. So what's really going on in this search function is we're just doing a pets find meaning we're taking the pets class we're saying hey find me all the records in pets. Then we're making what's called an active data provider which is something we haven't touched on yet. It's kind of like a class on steroids. It does all the providing of the data which is why it's called a data provider. So all you really need to know is that it's providing data. Typically you use these four widgets. Then we're saying this class the pet search. We're going to load the params. The params are that array that we shot out. Let's look at those again. So it's going to load this right here. Actually it's going to load that right there pet search. This is how it finds it because that's the name of the array pet search and then this is the actual data that it's going to load. So you can see it lines right up with the you guessed it the column names and there is our name TES because that's what we searched. So that is the actual query it's going to build. It's pretty slick, huh? And there's the actual SQL query that gets generated from that select count star from pets where name is like blah blah blah. And it does a couple different queries so that it can get a count. It can get the actual rows etc etc. Unicode is limiting 20 because it's doing pagiation. Pretty slick. Let's go into here. If it's validated models can be validated. What that means is that the parameters have to be within the rule set. Let's go back to the rules here. These rules. That's where validation comes from. So if we enter a name that's 300 characters long it won't validate because its maximum is going to be 255. That's what validate really does. So if it validates then we're going to return that data provider which is just provides data. Otherwise we're going to jump down here and we're going to say query filter where and then it adds in the parameters that it loaded from that query string. This guy right here and then it's going to say query and filter where and this is where that SQL query actually gets generated right here. You're saying and and and and then you're going to return the finish data provider. Kind of confusing and you may need to look into that a little bit more. Typically you won't mess with this until you get into advanced topics like when you actually want to search on a related table which we'll cover in a future tutorial. So enough about models. I know your head's probably swimming at this point. We're going to go into the controller and remember the controller controls the flow of information in and out. So here's index our index page. This is the default page. Before we do that we should probably look at the behaviors right here. You can define behaviors which determines how the views behave. You can see how delete requires post. What does that mean? That means you cannot actually do a route to delete. You can't say delete. See method not allowed method requires post. But if we go back here let's actually go to the pets sorry but if we go we'll go to delete this animal out. Notice how it's saying do you want to do this if I hit yes which I'm going to do it actually makes a post in the background loads the page and you can see how it's now gone. Alright so anything that starts with action is a view. So action index action view. So a view view is kind of confusing it's just going to load the view file. It's going to load the create file. It's going to load the update file. Delete doesn't actually have a file it's just going to redirect to the index. So when it does that redirect it's going to load you guessed it the index file and we're going to keep scrolling down and this find model function is used a couple times. You can see it's actually used in delete. So when we and let's go here when we go to go to delete actually let's go to view. You can see how it's doing a query parameter of id equal to because that's the record id or the pet number. So we're going to go back in here. What it's doing let's go to view. You can see how this takes a parameter called id and it's going to render the view file or the file named a view under the views if that's not confusing enough and it's going to give it a model using find model. Now let's break this down a little bit because that's bloody confusing. So what it's going to do is it's going to load the controller is going to come in and say what are you looking for it does that based off the route pets slash view. So it's going to look for the pets controller and then in the pets controller it's going to look for the action view and if you are in update it would look for action update and notice how it's got a parameter id too. That's how it knows which record to look at. So if we stick with our update where are you at here yeah update. So in the pets controller it's going to look for update it has to have that id parameter then it's going to say I need a model which is a representation of the data it's going to say find model which is down here which is going to actually use the pets model to find that specific record and if it doesn't find it it's going to say not found page does not exist so let's test that out. I'm going to give it just this huge number that I know does not exist four four not found does not exist. So that's a really good way of keeping people from trying to modify things that just shouldn't be there and you notice how in our debug we now have a red one meaning there was a failure and you can actually go in and see you know file not found exemption. Now if we take that id out of there see how you get a different one you get 400 bad requests missing required parameter id. That's all being auto-generated for you. Alright so let's go back to our update here. So once we have our model you know we've actually gone to the database we found that specific record we're saying if model load and then we're going to take the post from you know this is the essentially the PHP post variable is what that is with some other magic in front of it. So if we can load that post into the model and we can save the model then redirect to that view otherwise we're just going to load the update file. So it's pretty self-explanatory what's going on here I mean if you know just rudimentary PHP you can kind of eyeball this and figure out what's going on. Same thing with create you know if we could actually load it you know if it's a post then go to view otherwise go to create so let's actually go to this and test that out. So when we click create notice how it does the create view but if we fill something in here just why not because yeah see that's got to be a number that's what I love about E. No picture don't care huh yeah I got to get an actual date format. Database where are you? Save me my SQL save me all right so we're going to put that in there. Now notice how we haven't even tried and it's already kind of doing this here so like if we delete that and we go there that's called Ajax post back that's what that is so this is you hear the term Ajax thrown around quite a bit what's already baked in so you don't really have to mess with it and you can turn that off in properties but for this specific tutorial we're just going to leave it on so if I type in a string notice how must be a number so all that's already in there for you. Now when I hit create notice how it puts me on view let's go back to that that file here so what we're saying is if it can load the request or the post data and save it then go to view meaning we've already created it otherwise just go to create so that's the magic behind that. Now the individual view files these might take a little bit of explaining but we can go through them so if we go to index let's actually go to index on our page here you can see how it displays this grid with these little buttons and the create button and all this stuff so let's look at that super quick you can see there's our breadcrumbs the breadcrumbs are the little strip across the top of the page here at legend and navigate and there's your title and right here is your create button and then we have got a search or we've got a grid view widget the concept of widgets may be a little new to you basically it's code that already exists that you can just simply call so this we're making a grid view class from the widget and then we're giving it a data provider which remember data provider just provides data so it's basically a collection of models or I should say a a fancy array of models and then we're giving it a filter model or the search model which allows you to do the fancy searches up here so it knows intrinsically what it needs and then we have the different columns like we have a serial column and then we have our different our different columns from the database you notice how this one says n text that's how you format it automatically and then cost etc and then you have this action column so we're going to look at serial and action the first and the last so the serial just puts a number right up the front here one two three the action these are the view edit and delete buttons now if we go to let's just say view and then we're going to go look at the view file here same thing we've got our breadcrumbs got our title we've got our buttons up top you notice how this one actually puts in a confirmation dialogue there's the code that generates that and then we once again have a widget this one's a details view which is different than the grid's view this is the details that's the grid so the details view is pretty much just for looking at a specific record and then once again we have our columns in there now if we go to update you see how we got a whole lot more breadcrumbs and we've got very little code but it says this render underscore form model equal model what's that mean well let's break this out here let's actually go to update you notice how it displays a heck of a lot more than what we're seeing we got all that breadcrumbs but it's displaying this huge form well this is you know a prime example of code reuse we have this underscore form file which is right here and that is what's being loaded and this is used when you update or create the model is the parameter passed by the controller so let's actually go into update you see how we got the model here and we're saying you know this redirect and then we're giving it the model id but if we do the update we're actually giving it the model class itself that's how that gets in there so when we go to update it has this right here which tells it what it is so there's our model which is actually a app models pets and then we're passing that as a parameter to the underscore form file so it can be reused over here as well there's our model so whenever you're wondering what something is like if you want to know what a form is it's actually a slash widget slash active form and you can dig up that class and look at the code when you're wondering what this is it's actually a web view you can you know dig up that code and look at that too if you're wondering what type of model you've got you've got a app or sorry an app models pets which we've generated so then we've got our form fields and this is an active form which means it talks to the database um and then from there we're just loading the parameters from the model you can see we got form field and then we're giving the model and then the field within the model and then we have a different type of input and you can do things like check boxes drop-down boxes text areas all those things you can see how like these are text inputs but this one is a text area so it auto generates some but not all and then you've got a submit button which depending on what you're doing is it a new record you're going to create otherwise you're just going to update and you determine what it looks like based off the class depending on what you're doing here so that's really all there is to it um that is kind of a general overview of crud um i would advise that you kind of you know make a couple database tables and generate some of your own crud and just kind of play around with it and get a feel for what it does in the background um that's it for this tutorial um if you like this let me know if you hate it well don't let me know no i'm just kidding just let me know um trying to get a feel for how i want to present these tutorials because ye is different than most of the other things that i've done in life so i want to present it a little bit differently and try to give it the justice it deserves um you can also join the void realms facebook group i think we're pushing oh man we're well over 300 people at this point i haven't actually looked at the count i've been very busy but every time i have a question i actually go into the void realms facebook group and then people smarter than me answer the questions that i pose so i feel very stupid every time i go in there so that's it thanks for watching