This post was migrated from Justin’s personal blog, 'Codethinked.com.' Views, opinions, and colorful expressions should be taken in context, and do not necessarily represent those of Simple Thread (and were written under the influence of dangerous levels of caffeination).
Go here if you want to see an index for the entire series.
In the last part of my series on Rails 3, we got up and going with Ruby, RubyGems, RVM, and finally Rails. It may have seemed like a lot of overhead to get up and running, but keep in mind that RVM only needs to be setup once on your machine, then you can use it on as many projects as you would like.
In this part I want to create a single static vertical stripe in the application. We are going to do this by creating a route which will map to the root of our website. We are then going to use the rails executable to generate a controller and some views to go with our route. In this post we are going to focus entirely on getting the entire pipeline running, but without a database at this point.
If you’ve used Rails before, then you probably know that it is big on convention. Everything has a default place, and the project structure is no exception. If you were to open up your project folder, you’ll see this:
Sure is a lot of directories! For now, let’s just focus on three of these folders:
- app – This is where the code for your application is going to go.
- config – This is where your configuration is going to go.
- public – This is the website itself. All of your static assets will go here.
If we look inside of our config folder, we will see this:
At the bottom you’ll see a route called “routes.rb”. Guess what goes in there! This is where all of our application routes live. The routing DSL in Ruby is very powerful and expressive, but let’s just start off with a very simple example in order to get that nasty error to go away (you know, the one that we had at the end of the last post in this series).
If you scroll down in your routes.rb file, you will see a commented line that starts with “root”. There are a lot of comments in there, so if you don’t see it, no worries. What we are going to do is to create a route which is going to map to our domain (the root of our site). This way, when someone hits www.your-domain.com, they will be routed somewhere.
So, let’s go ahead and leave the root route the way it is, but uncomment it:
root :to => "welcome#index";
And so now when you refresh your website (just run “rails s” if you shut down your server) you should see the error “uninitialized constant WelcomeController”. That should give you a bit of a hint about the route syntax that we entered above.
The “welcome” that you see on the left side of the hash sign is the name of the controller. This is why Rails is looking for a “WelcomeController”. The “index” on the right side is the name of the action. So we need to provide it with a “welcome” controller that has an “index” action…instead of just standing around, let’s make this happen!
Creating The Controller
Remember in the last post when I said that you can run the “rails” command and it will show you a bunch of commands that you can run? Sure you do. Well, if we run it again we will see that there is a command called “generate” which we can shorten to “g”. So if we run this command:
We will get another list of commands. Guess what this command does? Oh yeah, it is generating application content. In our case, we want to generate a controller. But we don’t really know the syntax. So let’s run this command:
rails g controller
And voila, it shows us further options and gives us usage examples. Isn’t Rails just so nice and helpful? Can you guess what our command is going to look like?
rails g controller Welcome index
This command tells rails to generate a controller named “Welcome” with a single action named index. In reality though, it’ll generate far more content, like this:
Whoa! What is all of this? Well the first thing it generated is the controller, and it placed that into “app/controllers”. Again, this is all based on convention. Notice that the controller filename is “welcome_controller” and the class name is WelcomeController. Again, convention. Rails will find and load this controller based on these conventions.
The next thing it generated is a route which is hardcoded to “welcome/index”. This will get spit into your routes.rb file, and you can either ignore it or remove it. The next line you see is “invoke erb”. This line is telling you that it is invoking the erb generator in order to generate the next two files (the generators are pluggable!). In case you are unaware, erb is the name of the default view engine in Rails. As with most tools in rails, you could swap this out for an alternate like Haml.
Next you’ll see it is generating some tests with “test_unit” (which we will be swapping for RSpec in a later entry). Next you see it is spitting out a helper, and finally a test for this helper. At this point, go ahead and refresh your app. You should now see a view rendered in your browser! Woot! You are now an official Rails developer, time to update that resume!
Just kidding. Sit down.
First let’s go check out the controller. Open up your app in your favorite text editor and go to the “/app/controllers” folder and open up the “welcome_controller.rb” file. What is in there is pretty terse. It is exactly what we told it to generate:
class WelcomeController < ApplicationController def index end end
Okay, so we have our controller class, which descends from ApplicationController, and it has one method in it called “index”. The root of our site is getting mapped to “welcome#index” and so we know that we are looking at the right controller and action. So how does it know how what to render? Well, convention rears its head again.
Go back and look at your app’s folder, and go into “/app/views”. In there you will see two folders. One is called “layouts” and the other is called “welcome”. You have probably guessed that the “welcome” folder contains views for the WelcomeController, right? And I bet when we open that up, we are going to see something with the name “index”. Go ahead, open it up!
Yep, right there is a file called “index.html.erb” and in this file is a tiny chunk of html:
<h1>Welcome#index</h1> <p>Find me in app/views/welcome/index.html.erb</p>
Okay, so this is the text which is rendering in the browser, go ahead and change it and refresh the page, just so you believe it.
<h1>Rails Baby</h1> <p>Where babies go to learn Rails.</p>
Sweet. But that isn’t an entire web page, where is the rest coming from? Again, you might have guess that the layouts folder you saw inside of the views folder might have something to do with it. Let’s go look and see what is in there.
There is a file in there called “application.html.erb” which just happens to be the root “layout” for our application. If you look into this file, you’ll see that all of the missing html is located within this file. You’ll also see a few default code blocks that are included in this file as well, but the one that we are going to pay attention to is this one:
<%= yield %>
If you’ve used Ruby before, then you may be familiar with the concept of “blocks”. They are essentially chunks of code that you can pass to a method. In order to invoke a block that is passed to a method, we use the “yield” keyword. This works in essentially the same way. When a view is to be rendered, a layout is also selected and then the view is rendered into the layout using the “yield” keyword.
When an erb view is rendered it is usually going to be rendered with a layout. The default layout for an erb view is application.html.erb in the layouts directory. There are ways to change the default layout, and ways to nest layouts, but we won’t touch on those until later.
You’ve got some nice assets in your project and you want to show them off, right? Ha, right. Anyways, if you check out the default Rails install you’ll see that it uses Prototype by default (this is changing in Rails 3.1). Well, I’m a jQuery man myself, so we are going to need to change this. When we generated our app I could have passed a command line parameter that would have left Prototype out, but that wouldn’t have been fun, would it?
If we look back at our application.html.erb file you’ll notice a tag that looks like this:
What we are telling Ruby to do here is to grab us the set of tags that is defined with the key “defaults”. Left as-is this is done way down in the bowels of Ruby, but we can very easily override this. Just go look in your /config folder of your application and you’ll see a file called “application.rb”. You’ll want to get quite familiar with this file, you’ll come back to it pretty often. In this file is where a lot of application specific setup happens.
If you look in the file you’ll see a line that looks like this:
Now we have to remove Prototype and add jQuery. Fortunately there is a super easy way to do this. First add this line to your GemFile:
group :development, :test do gem 'jquery-rails', '>= 0.2.6' end
You haven’t seen this syntax before, but what it does is create a group of gems. This just insures that this gem won’t be installed into production, since all it really does is create a helper to install jQuery. Then go to your console and run:
This will run bundler and install the gem which will create a new generator for you. So now you can execute:
rails g jquery:install
And you’ll see that it will remove all of the Prototype stuff, and add in the jQuery stuff. It’ll prompt you to overwrite rails.js, just say yes! You’ll notice that if you run “rails g” you’ll now see this generator in the console, Rails 3 is super extensible!
Assets – CSS
And finally you’ll see this asset tag:
<%= stylesheet_link_tag :all %>
This is fairly self explanatory, it’ll render all of your css files located in /public/stylesheets into your header. If you need to you can also use expansions in the application.rb file to include stylesheet_expansions as well.
So now you have seen a very quick example of creating a route, creating a controller and view, and hooking them up together. You also learned how to include your assets into your site so that you can start to build and style your application. In the next entry I am planning on going a bit further and I will create a model along with a corresponding controller and show you how you can start putting data into and pulling it out of the database.Previous Post Next Post