2.1 Scaffolding Projects
Now that our application is bootstrapped and can serve itself, we will begin iterating over its feature set. In this course we’ll be building a simple project and task manager. The first step towards realizing this app is to create a class that represents projects. In this lesson, you’ll learn how to scaffold a model for projects.
1.Introduction2 lessons, 14:01
2.Building a Rails Application11 lessons, 2:09:35
3.Conclusion1 lesson, 02:23
2.1 Scaffolding Projects
So, now that we are acquainted with the Rails folder structure, we can start doing things. Since we are going to build a project manager, it is important that we start developing a way of storing information on those projects. The way we do it with Rails is quite simple. We're going to create a new scaffold. A scaffold in Rails is a generator that will create a controller, a model, a set of views, and also a migration file, amongst other things. We're going to type in the Rails generate command, which basically will generate a bunch of files and folders, and then the scaffold command. The scaffold command does exactly what I've told you, and we need to tell this command what kind of model we will be building. In this case, I want to type in project, as project will be the name of the model. Now, after we tell the model name, we need to create a set of attributes to that project. I want to give the project a name and also an end date. The name will be a string, so you will typically type a colon and then a value that matches the type. String is a default one, so we don't need to use colon string at all. However, for the ends_at, which is going to be, for example, a time stamp or a date time, or even a date, I need to explicitly type that. I use the date to match the nature of this attribute. I want the ends_at attribute to be a date, so I tell it so. So basically we're going to create a set of files and folders that will support the creation update and deletion of these projects. Each project will have name and a date. So pressing Enter now, you will see that all of these different files are created. As I have mentioned, we'll have a migrate folder with that migration, the project model, then some tests around this model. The resource route, and this is something that I'll explain later. Then we have the projects controller, all of the views to show, list, edit, and create new projects. The controller tests, then a projects helper file, which we can store methods into and also use in the views. Then we have some asset files like aid projects, coffee script file, and a Sass file. Since we are generating a scaffold, it also generates a scaffold template file. So we've created all of this, but now we need to do something else. In fact, let me open a text editor really quick and go to db migrate and add this file with this funny name. It is in fact a timestamp with a more descriptive name, it is called CreateProjects. And this class actually creates that table with a string column called name, and then a date which is called ends_at. Notice, also, how the time stamps are also included. These two time stamps are created_at and also updated_at. You will see these two fields in the table because that's what this instruction does. It creates those two columns, which are automatically updated whenever creating or updating a new or existing project respectively. We do have this migration file but we'd to run it. So if I go ahead to the terminal again, just opening a new terminal, I can type in rake db:migrate. When doing this, the migrations will be run from the very last migration that was run. We don't have any, so we'll just run all of them. And it's just one, so press Enter, and the projects table will be created. From here, we'll be able to the run the rails server command to boot the server up, and see what changed. Okay, let's open our browser, type in localhost3000, and there you go. We are still in the homepage. It's still there. But now I want to change the address in order to go to /projects. When you go to /projects, you will go to the index template and our application. You see that we have a header with what doesn't seem, but it is, a table with a name and the Ends at. When you click on New Project, we will go to a new route called projects/new, and we'll be given a new template. New project with a name field. I'm actually going to type in for example, My First Project. And then I can select the date it ends. For example, December 31st. The end of the year. If I click on Create Project, the project will be successfully created, as you see on top. And indeed, we do have it. There's the name and the date. Notice how we are going to projects/1. 1 is the ID of the project because we haven't created any other project. This is the first one and it gets the ID of 1. We can go back to the list of projects if we wish to. You can see the table is now filled with one single record. We can choose to edit it, and we will have the populated form. Let's say for example that instead of going to December 31st, we can go to one day after it, so January 1st, of the following year. I can update the project, and notice how the date changes. And we still get the very same ID. If I go to the list of projects and hit Destroy, this should pop out a question mark. There you go. The confirm prompt allows me to confirm my action, which I'm not going to. I'm going to cancel, because otherwise, I wouldn't have that project any more. Notice how easy it was to implement such a feature. With one single instruction and an operation to migrate the changes in the database, we are able to manage the whole list of projects. We can list all of the projects, view a detail of one single project, create and edit them, and also remove it. Now, let's go step by step and see the results of that scaffold operation. I want to go to the config/routes file. As you can see, we have this resources projects line added to this block. This single instruction created several different routes. The way I'll show you this is by typing rake routes in the terminal. As you can see, we have a whole list of different routes. The index, so /projects, then /projects but with the post method. This will allow us to create a new project. Projects/new renders the template to create a new object. Actually, this route displays a form that gets sent back to this route. Then we have the edit project, which is the same form, but with a populated object. Then a single project, so projects and then the ID of the project. Then patch, put, and delete are actually the same route, but with a different HTTP method. This is what is called a restful set of routes. This structure you see here, /projects/projects:ID, and the several different variants, are called restful routes, because they represent a resource and ways of changing it. These two auxiliary routes basically render a template, so that we can reach to those restful routes. We depend on the HTTP method, rather than the name of the route. Okay, so this is all about the routes. But there are other things that we still need to take a look at. Namely, the controller. So, let's go to projects_controller. Here, you can see a bunch of different methods already. The index method is mapped in order to list all of the projects. The show method will list one single project, the new method will create a new project instance variable, so that we can populate it. Then the edit method will render the form to edit that project. In line 26, you see the create method. It creates a new project, and tries to save it. If it is saved, then we're going to render a specific action, depending on the content type we wish to fulfill. Usually, we're going to resort to HTML. So basically, it's going to redirect to the route for that project. In Rails, there is a strong relation between a resource and its routes. So, when passing the project instance variable, it is going to automatically assume that we want /projects/ the project's ID. We're going to pass a notice message saying that the project was created. In the case that it's not saved, we're going to render the new template again, and attempt to change the data in order to be successfully saved. As for the json format, we're basically going to render the show template in json, essentially to just print the project's data into a json format. The same goes for the failure state. We're going to render the @project.errors with the appropriate HTTP status. The update method is really simple. It does the very same thing, but instead of saving, it tries to update the data for that project. The string method here, attempts to destroy the project and that's it. If it is successful, it redirects to the list of projects. Otherwise, if it's json, we just print a header with no content. Don't worry about these private methods as of now, we're going to focus on them later on. If there's anything that I want to mention, is this set_project method that identifies the project instance variable. Which is called, in this method, before_action. You can see that the show method and the edit methods are actually empty, but they do have some code being run before. Before_action sets a method that's going to be called for each of these actions. So the project is still going to be loaded but it's just tucked away in its own method. Next we're going to focus our attention on the model. Under models/project, you will see this very simple class. The project class will inherit from active record base. This latter class contains all of the methods that you need to have in order to list the projects, identify one specific project, delete them, and also update their records. Every bit of functionality in order to retrieve information and store information, from and to the database, are there. We won't need to do anything in regards to defining this project class. The code is already developed, we don't need to do anything else. Next, we have the views folder, which contains a set of layouts. And in this specific case, the projects folder, which contains all of the templates that you've seen so far. For example, the html.erb template for the index contains a paragraph which just prints the notice message in case there is one. Then we're going to declare a header called listing projects and a table. For each of the projects, we're going to loop through all of them in the list. And for each one, we'll print a new row in the table, with the name ends_at, and also some links, in order to show, edit, or destroy that specific project. Notice how we are using the same mechanism as in the controller. We are resorting to the project variable here, which is a project model. And because of that close relationship between the model and the routes, Rails automatically defines a proper route to redirect to, in order to retrieve information about that project. In the edit method, we can resort to the edit project path in adding the project as a parameter, and it will go straight to the form in order to edit that project. In the destroy method, we use the same project variable, but with the delete method. Remember when I showed you the routes in break routes? You can see here that this delete verb is the same that goes in the method option here. We also want to pass in a confirm method that Rails automatically identifies as a pop-up, asking us to confirm the operation. We do that by passing data, and then confirm with the message. This is just one of the many templates that you have in the projects folder. You're free to browse through all of them and try to understand what each of them does. It's basically HTML with interpolated Ruby. As you can see with the pair of tags with open tag and then percentage. And if you want to actually print something, you add in the equal sign at the beginning of the tag. If you don't want to, you can omit the equal sign, and nothing gets printed out. Okay, so that's it for the first steps in building our application. We now have one project in our system fully working.