In this lesson, we'll continue implementing our business data model by creating code to list and create orders.
1.Introduction3 lessons, 12:00
2.Building the API10 lessons, 1:53:48
3.Conclusion1 lesson, 01:08
Now that the table model is up and running, we can move up in our data model. Now it's time we pick up on the orders. So actually, instead of going to the editor, I'm gonna go to the console and type in rails-api g scaffold, and just type in order. Now the reason I'm using a scaffold is just so we don't have to worry to much about the code that generates the orders and lists all of them and stuff like that. Now the order model will need to have some attributes. The first one will be for example the name of the customer and let's take the chance and add in an email. You don't really need to worry about this right now, but I'm just going to add it right away just in case. We're gonna focus on a topic or two that's related to this email so bear with me. Now, we need to refer to the table, because we want to order to be referred to a table, so we use table references the same way as we would do with the Rails generator. And for now, that's it. We're just going to refer to the customer's name and email and a reference to the table he's sitting in. So let's just press enter now and generate that whole scaffold for the order. Now we're gonna have to make some changes of course because we don't want to include every single aspect from the scaffold generator. Let's start by going to config/routes. First of all we have resources orders here without the new in edit. But in fact what we really want is just to have the option to create an order and to list all of them. We don't really want to update orders or delete them because that wouldn't make sense. So we're just going to stick with only, and this will only include index and create. Also there's one thing that I want to do. I want to make sure that I include the process of creating an order inside the table's resources. The same way I want to have the index route just on top so slash orders like this will exist and not in here so I'll just remove this one and step two, create like so. We will only have something like tables and then my table in specific and then /orders. And here, we'll just remove create like so, and we're done. The reason I'm doing this is merely educational. I wanna make sure that you know that you can use more than one specific resource route with different instructions, with different possibilities. In my specific need I want to list all of the orders regardless if the table but then when creating a new order I want to make sure that it goes to this very table. Therefore the url. So we're good on the order's routes now let's go to the controller for example. Let's choose order's controller and for now I want to for example, remove the show action. And also de-update and destroy methods. These are also going to be removed because we don't need them. We only wanna focus on the entire set of orders and creating a new order. Now, as for the create action, we want to reach out to a table, so we use table.find(params[:id, or better, table_id]. Remember that this parameter has this very name in the URL. Now, the order will be something like picking up on the table. Then orders and then .build, and then we pass the order parameters. Also remember that the instance variable called order will be set for the specific show update and destroy. Well since we don't have either of them, we can safely remove this code which makes it a lot cleaner. You could keep the code, of course, but since we are not using it, I think it's just best to remove it. So there you go. Now, as far as the controller goes, I think everything is in order. Now, we need to go to the model. As you can see it already has a reference to the table but the table doesn't have a reference to the orders. This is necessary because we want to create an order based off the table so we use, has many orders, which will create the necessary amount of code to generate an order that's related to this table, just like we saw in the controller right here. So in line 14 this orders.build method exists because of that previous relationship directive. Everything else looks just fine. If we save the order we're gonna render that order, or otherwise the order's errors. And that's it. That's all there is to it for now. In regards to the controller, the routes, and also the model loop which we've seen lastly. Now in order to test this out we need to put up the rail server. There you go, and now we're going to pick up on that bin/curl file, remember that. We're going to create a series of functions, and then we call each different one. So, what we're going to do here is, first of all, list all of the tables. I'll create list_tables method just like so this function in BASH will then close the contents for listing all the tables. This is not actually list tables but rather create table. So create table is there and now we need a new one for create order. I mean it's not exactly that hard to list all of our orders or tables. We just type in curl http://localhost:3000 and then the resource, either orders or tables. That's really not that hard. What is hard is to shove in some data and all the headers over and over again when creating a new resource. So in this particular case, we'll go, for example, and create an order for the very first table. This is going to be hard coded just for the sake of simplicity, but you can always change this value based off a variable, for example. But for now I'm just gonna make this a lot simpler. So let's do something that's very unlike the previous one. So we're going to simulate a post request. Then we're going to pass in a content type header. And then send the data that comes for example, from an order.json file. Okay. Now all we need to do is to edit that order json file. So we'll use bin and then order.json. We'll just edit it really quick. The orders data will be something like this. Let's just pass in the quoted variable. There you go. And this is going to be an object as well. As for the data that goes inside, we can pass in, for example, my name and the specific email. So, we'll go to firstname.lastname@example.org. I think there's something's missing. We need to replace these with quotes. Not for place, but rather wrap around the word, and now it's okay. I'm not using the table ID reference here, because it's already in the script. That's why I've used this nested routing. Let's see if this works, I'm gonna go to another pane on tmux and I'm going to run bin/curl, but in this particular case I need to pass in an argument that's going to through a script. So, I'm gonna go here again, and at the very end I'm just going to call whatever's on the first argument. Basically I want to run the function with that specific name. So let's press Enter now and it's trying to do something but it seems that something's not really okay. As you can see, we have a bunch of HTML being printed out and that's not good. Also because it's very hard to understand this, we're going to go to the server and check the logs. Yes, again with the migrations. That's fine. Let's just run rake DB migrate. There you go. Now the orders are in place. Now let's try and write the script again and there you go. So, in this specific scenario, we were creating a table, but now we're going to create an order. So let's press Enter now, and it seems that something is wrong. Let's go back to the server log, this is actually pretty good that it's happening to us. Because not everything can run smoothly. Or can it? It's a good way to force ourselves to read some logs and to check what can be problematic in your own development. Our error seems to be a syntax one so that's actually pretty easy to fulfill. Let's go to the orders controller because that's the one we were messing around with, it seems that we missed this parenthesis, so now it's a good chance to run this again. It seems that the error is still persisting. Now, what we do have is a 500 error. Let's see, no method undefined for order_url. Of course, the order URL doesn't exist because the route isn't there, we've deleted it, remember? We didn't include it in the routes. So instead of printing out a location, I'm just going to omit it. The problem with this was this location variable that looks for the order URL which doesn't exist because we deleted it. So from here we should be able to make it work. There you go, everything runs smoothly now. There's the headers for the request. The headers for the response and the actual response. So we have an order with ID of 2, a name, an email, and the reference to the table ID. There you go. So, in regards to the orders, we can now create new orders and also list them. In order to list all of our orders, we'll just print out http://localhost:3000/orders. There we go, ID of one, ID of two.