Rails – What Goes Where

Homes for Your Logic, CSS, HTML, and More

Rails is a framework. (If you didn’t know that before starting this article, you might want to hit up some other beginner articles first.) Framework makers love separating files into different folders—they’re the obsessively tidy folks in the world of code. Simple logic would follow that Rails involves separating files into different folders. This would be true.

But what, exactly, goes where?

        <span id="more-3471"></span>

A Place for Everything…

So there you are, sitting at your computer, nigh wiggling with excitement. You’re tickled pink about doing your first real Ruby on Rails app. You hit up the command line, and you type

    rails mynewproject 

Ack!, you may exclaim. What’s this scrolling by? A list of new directories. OK, that makes sense—Rails is a framework, which translates to “many-many directories” in the ancient language of Devese.

It can be a bit overwhelming, or at least boggling, at first. With so many directories to choose from, how do you know where everything goes? Some things are somewhat obvious if you have any background understanding of MVC, but others are more Rails-specific and require some thought. Since there hasn’t been a simple document yet—that I’ve seen, anyway—to lay all this out for once and for all, I decided to undertake the mission. It’s a dirty job, yeah, but somebody has to do it.

Besides, I kinda like playing in the dirt.

Business Logic

If you haven’t yet, you should definitely read my article on MVC, the design pattern that inspired Rails. Shoo! Go on! I’ll wait.

We’re going to check out the app/ directory first. Yours should look something like this:

    app/
        controllers/
        helpers/
        models/
        views/

APIs

APIs are something new to Rails 0.10, which introduced ActionWebService. If you’re writing a Rails app that relies on an API to interface with another service somewhere, or if your Rails app can be used via an API, then the files with the relevant code go in app/apis/.

Controllers

Controllers are what makes up the meat of your program. Without your controller, you have nothing, because the controller is what makes it all happen. And controllers are all located in app/controllers/.

Models

Models are code representations of database tables—you give it a name, and tell Rails how it relates to other database tables. Model files go in app/models/.

Presentation Logic

Once you get past the nitty gritty code that actually does stuff, then you’ll want to put a pretty face on it. You’ll notice I left out a couple directories from the last section—that’s because they go here.

Layouts

Layouts are the Rails equivalent of including a header and footer file for various pages. You have a base layout file for every controller you create using

script/generate controller controllername

And it will apply for all of the pages displayed using the Books controller; it will call the appropriate individual view for each method that ends up needing a display. If you create a controller called Books, then you’ll find books.rhtml in app/views/layouts/.

Views

Individual view files are used for each method in the controller which requires display. You’ll probably have a method called edit, which requires a view because it generates the form to do the necessary editing. If you generated a scaffold for your Books controller instead of generating the controllers and models by hand, you’ll find edit.rhtml, list.rhtml, new.rhtml, and show.rhtml in app/views/books/. They appear within the layout described in the last paragraph.

Helpers

Helpers are little methods you can create to save time and repetition when doing HTML in view files. For example, there are several helpers built in to Rails to generate form elements with the correct name attributes and so on. You might want to create a helper to create the login/logout links across your site, for example. You’d put that code in app/helpers/application_helper.rb if you want it to be available to all controllers, or app/helpers/books_helper.rb if you want it to be accessible just to the Books controller I keep yammering on about.

Presentation Illogical

But wait! There’s more! Remember presentation stuff that doesn’t require Ruby logic—CSS, Javascript, images, and pesky little 404 notices? For this section, go one directory up—back out of apps/ and enter public/.

Stylesheets

Hooray for CSS. Your stylesheets go in public/stylesheets/. Linking to them is as easy as (no .css):

stylesheet_link_tag “stylesheetname”

Javascript

Javascript belongs in external includes files, not your views, layouts or otherwise! Your .js files go in public/javascripts/. You can include them using the following syntax (no .js):

javascript_include_tag “javascriptname”

Images

I guess you’re seeing the pattern at this point—public/images/. ‘Nuff said.

Error Pages

404 and 500 error pages are in the root of public/. Customize ‘em. You know you want to.

No Comments

  1. Tim Almond says:

    Amy,

    That’s a great post. I really must try this RoR stuff. From what I’ve seen, it reminds me a bit of a mainframe 4GL I once used which was orientated around the data – get from the data to the process with the minimum fuss, unless that’s what you want.

    Have you done anything with regard to role-based security in Rails?

  2. You really are putting a fantastic resource together on this site.

    Thankyou :-)

  3. Is there any way to have Ruby/logic on the ErrorDocs? Even if it’s just "You were looking for " ?

  4. Magirus says:

    Amy, thanks for your tutorials! Although I think I don’t understand the wits in all of them (no native american tongue), they are welcome lights in the diffuse twilight.

    Two things: * Please link your tuts on the RoR Wiki Site, so newbies will find them. * Can you write something about the big picture? How all of these design decisions go together?

    We all hear lots about data, models and controllers, but what about the processes? I mean, users don’t edit data in your app, they want to get tasks done and those tasks might require touching more than one datamodel. They usually require touching a lot and doing this in the right order. Is there some concept that supports this?

    Best regards…

  5. Jarkko Laine says:

    Joshua,

    Yes, there is. You can point different errors to either static files or to some dynamic page. In lighttpd for example, you can say this in its config file:

    server.error-handler-404 = "/dispatch.fcgi?controller=error&action=notfound"

    (Assuming you want to handle 404’s with that controller/action)

    There is same kind of config in Apache, too. Search for apache docs for more info.

  6. CJ says:

    Nice article.

    Can you explain and draw UML-like diagrams on the relationships of the different file names, directories and database tables in an app?

  7. Thank you for the article, and thanks to Jarkko for confirming what I thought about how to customize the error pages in Rails by creating error actions. I need to use my app’s layout on my error pages.

Hey, why not get a shiny
Freckle Time Tracking
account?