Join Kevin Skoglund for an in-depth discussion in this video Rendering templates, part of Ruby on Rails 3 Essential Training.
Now that we have our routing rule set up, we are ready to take a closer look at how the controller does its job. As we just saw, routes will determine which controller and action get used. At that point the controller takes over, and the controller's job is to control. Specifically they make choices about how to respond to the request that the route just handed over. Now as you might expect it's very common for controller actions to use one or more 'if else' statements inside them. If something was found in the database then do this; otherwise do that. If a user is logged in then show them the page; if not, show them a login form.
That's a very common kind of thing that a controller does. We'll explore controllers a lot more as we build out our application, and we are going to work a lot more with the model later on and see how the controller interacts with the model. But for now, I would like to begin by looking one of the biggest choices a controller makes, which is which View template to use. How does the Controller decide which View? So as we saw earlier, we have our controllers' folder, and we have a demo_controller that we generated. We also have our Views folder which has a demo folder in there for templates, and we have a starting template called index.html.erb.
And I'd like to make a duplicate of that template. You can either do that by going to your text editor and just saving a new file there. What I am going to do is a shortcut. Just go to the File menu and pick Duplicate. That will make a copy here, and I am going to change the name to hello, and then very important get rid of copy at the end. So that it has the correct ending. We'll talk more about those endings when we talk about the templates themselves. But for now we have two different templates, one called hello and one called index. I am going to open up hello just so that it's something a little different. Just make it say Demo#hello and save it,and let's open up index and let's change this to say something different like Hello from the Index Page.
Okay, that should be distinct enough that we can now tell the difference between them when we see them very quickly on the screen. The next thing I would like to do is fire up our web browser. So go into your command line. Make sure you've navigated into your Rails application and launched the server. Rail Server, so now it boots up. Let's go into our browser and I am going to click on demo/index, there we go. We see the new Hello from the Index Page. Now let's try demo/hello. All right, so now we get the hello page. So let's take a look at what's going on here. Open up the demo_controller and you will see that we have an action for index.
But we do not have an action for hello. So this is Rails' sensible defaults at work. What is happening is it's saying, "Oh, if I get a request for index, do whatever is inside this index action and as a default behavior, go ahead and load up the index template." So the choice is made for us by the framework. That's a sensible defaults at work and it's great that it just does it. We don't actually have to specify it. It also does it the other way around. It says, "Oh, if I get a request for hello and there's not a hello action there, go ahead and see if we can render the hello template." All right, it doesn't raise any kind of error.
It just goes ahead and renders up the hello template to us. Now let's just show what happens if we try something else. Let's just try demo/something unknown action. So we don't have a template or an action. Now we get an error. Now it says, "I don't know what to do with that," and that make sense. You wouldn't want people to just be able to type random things into your website and be able to get things back. You only want it to respond to the request that you're prepared to respond to. So let's go ahead and make another action here. def hello, just so that we have that.
We know that we don't need it. we know that the default is that it would show the template. But I want us to go and have two actions that we can begin to work with. So what's happening here in the index is it is implied that it is doing a render statement. We are going to be using render a lot inside the controller when we decide which thing to render. The most common way to do it is to let the default behavior kick in, to have nothing there. But I want to show you how we can specify it. So the old way of doing it is to say render an action hello, okay? This is the original Rails 1.0 way of specifying what we want to render.
And what we are saying is render the template that you would render as a default for hello. It's a little bit convoluted, but that's what it's doing. It is saying if you are the hello action, what would be your default template, and that's what it renders up. So let's just try that, just to see what it does. So let's nowload up index and look at that, we get hello. We don't get the from index anymore. So it's rending a different template. Now this gets a little convoluted and confusing, because what if hello is rendering something else. What if we've got the hello rendering a different template, all right, or maybe hello is just rendering text? Let's say, for example, render text, we can actually just render text=> 'Hello Everyone!' all right. So now let's just try this, just so we see it.
Hello, hello everyone, and that's just the text that's rendered back to us. But if we do demo index, we still get the template, right, so it's confusing. So as a result, a better way to do it is instead of saying which action you want, go ahead and say which template you want. And if we specify the template, we have to tell it which folder it's in, and when I say folder what I am talking about this folder here. Inside the views, we are going to have a number of these different folders for a number of different controllers. So we just want to specify the full path starting at the Views folder, go into the demo folder, and look for the hello template there.
That's what we are going to be using. So let's try that and just see what that does. Same thing back, no problem. Now up until recently, this was the best way to do it. But now in the latest version of Rails, we can actually shorten it and with render we can just demo/hello, and that will work, or even better we can just say hello. And it knows well, since we are in the demo controller, if I didn't get told something different, then that's what I should assume. That's where I should look for this file. So if we did want to render something that was in a different folder, we would need to specify it.
But otherwise it's capable of assuming it. So it has a little bit more intelligence built into the render now. We can just say demo/hello or hello and either one will render up the hello template. So just a recap, the syntax for choosing what we want to render, the first is we can use the default. The sensible defaults built in Rails, which will just pick the template that matches the action name, and by far and away, that is the most common thing you'll use. It's great, then we don't have to type anything, no code to break.
It's just it will accept the defaults and we will work with the framework. So that's the thing you will use most often. Render action hello, that's deprecated. Try not to use that. The next one, render template demo hello, perfectly acceptable. It's a very explicit way of doing it, so it spells it all out. But it's a little bit long. The more common ways you will see are the last two. So if you don't use the default, I recommended that you use the last two, either render demo hello, if it's in a directory that we can't guess automatically, if we are not in the demo directory, which we would assume from the demo controller, then specify it.
Otherwise, just leave it off altogether and just render hello, plain and simple, render the hello template. It's nice and easy. So I think that's the one you'll see most often and that's the one we will be using when we are not using the default one.
- Understanding MVC (Model View Controller ) architecture
- Routing browser requests through the framework
- Responding to requests with dynamic content
- Defining associations and database relationships
- Creating, reading, updating and deleting records
- Working with forms
- Validating form data
- Reviewing built-in security features
- Authenticating users and managing user access
- Debugging and error handling