So here is the first part of the previously announced Rails Project Story, in this part we are going to understand the Rails directory structure, design a very basic database to start with, link it to our rails application, setup the rails database schema for it and finally try the famous scaffolding feature that everybody talks about.
It seems that I underestimated the amount of work this tutorial is going to take that’s why I’m a day late, because of that I will change the weekday each part of this series will come up from Saturday to Sunday and sorry about this delay.
If you remember our project is BookSwap, a small system based on users, it will give them the chance to exchange and swap books between each others from their online bookshelves that they create. so let’s get started:
Normally I prefer to get something up and running as soon as I can, at least to enjoy seeing results from the very beginning of my project work and this is what we are going to do with this project as well, so to start let’s decide what is the simplest database design we can start with?
Database Schema
Basically from the light definition of our project we can tell that this project includes two main things: users and books, and from here we will go, we need two tables, one to hold the users data and we will call it Users and another one for books data and we will call it Books and now let’s discuss the relationship between these two tables
Obviously every user will have many books, and many users can own the same book (I mean the same title not the same physical book), so the relationship we have here is the many-to-many relationship which requires a third table in our database called users_books, therefore our database should look like this (db model is generated using DBDesigner4):

As you can tell from the database model above, I have mentioned the common and very basic columns of each table; fullname, login, email and salted_password for the Users table and title, author, publisher and ISBN for the Books table and naturally both of them have the default ID column as well.
We will use MySQL as the database server for this application, it’s time to create the three databases we will work with on our way:
bookswap_production: This will be the database we will use when we finish our development work and ready to have a live and completely working web application, that’s why it’s called the production database, it should contain the most stable version of our database structure with the most stable version of our code that’s why we separated it from the development database.
bookswap_developmentt: As you can tell, this is the database that we will play with during our development process, whenever we need to change anything or touch anything related to the database this is the one we should be dealing with in order to keep our production database in peace.
bookswap_test: In a sooner part of this tutorial we will cover the testing of our application, we will write code that will test our code and this testing code will deal with a completely separate database from both development and production databases, it will deal with the test database as it will require a lot of data insertions and deletion while testing which we want to keep away from other live and development databases.
If you have a GUI for your MySQL server you can create the above databases from there or we can simply use the command line admin tool:
D:\\Projects>mysqladmin -–user root -–password create bookswap_production Enter password: ******** D:\\Projects>mysqladmin -–user root –-password create bookswap_development Enter password: ******** D:\\Projects>mysqladmin -–user root -–password create bookswap_test Enter password: ********
We will only create the databases now, we will not create any tables or relationships yet and actually we will do all that in Ruby and Rails after we get to know the directory structure of our rails application.
Generating The Rails Application
Before we get started with generating the rails application let’s just clarify few things, we are using Rails 1.1.6 for this application which got announced only few days ago (from the date of this post), so if you have Rails installed earlier before the update please upgrade before we proceed.
To generate our rails application we have to run the rails command, personally I have created a directory called “Book Swap” where I will store everything related to this project, including the rails app itself. So all I have to do now is to run the “rails” command in my directory with the project name to get my files generated.
D:\\Project\\Book Swap>rails bookswap
exists
create app/controllers
create app/helpers
create app/models
.
.
.
create doc/README_FOR_APP
create log/server.log
create log/production.log
create log/development.log
create log/test.log
I guess you agree with me that these are a lot of files and directories that Rails has generated for us, maybe we should give them a quick scan and try to understand what they are for and what we will be dealing with more frequently:
File Structure

app
This directory is the one that will contain most of our working files, it already contains four subdirectories (controllers, helpers, models and views), that is made to support the MVC nature of Rails, in brief the MVC methodology is based on separating our code into three levels:
First we have the Model which carries the core functions and responsible for all the data handling and manipulation, then comes the Controller which normally interacts with the model to retrieve data and prepare it to be viewed by the View which by its turn is the responsible of doing all the “show” business.
As for Helpers, they are the view supporters, when we reach the level that we have too much code in the view we better go and make a helper function and use it instead, once we start writing code we will get a better understanding of all these concepts which will happen very soon.
Behind The Scenes
All of these models, controllers and views are just the children of a bigger and more general parts of Rails, actually Rails is a union of different parts for each task which makes it more understandable and customizable to fit our best needs.
ActiveRecord is the part of Rails that’s responsible of interacting with the database and lets us deal with it as a complete object oriented solution, which really sounds like the model behavior (core functions and data manipulation) which is true, normally the model classes in our models directory are subclasses of ActiveRecord where they inherit the magic powers of it and get such strong tools to deal with the database.
“Active Record objects don’t specify their attributes directly, but rather infer them from the table definition with which they’re linked. Adding, removing, and changing attributes and their type is done directly in the database. Any change is instantly reflected in the Active Record objects. The mapping that binds a given Active Record class to a certain database table will happen automatically in most common cases, but can be overwritten for the uncommon ones.” From Rails API
Following the same path Rails also depends on ActionController for its controllers, which is the midpoint between the views and the models, it receives the web requests from one side, activate the corresponding action which will contact the model for few data objects and then render the views to show the results.
“Action Controllers are the core of a web request in Rails. They are made up of one or more actions that are executed on request and then either render a template or redirect to another action. An action is defined as a public method on the controller, which will automatically be made accessible to the web-server through Rails Routes.” From Rails API
And finally we’ve got the views which are ActionView templates, we will see how they are just normal html, js or xml pages but with embedded Ruby code inside which also known as ERb, this embedded code helps us represent the data with some behavior and have a better separation between our design and our backend code.
“Action View templates can be written in three ways. If the template file has a +.rhtml+ extension then it uses a mixture of ERb (included in Ruby) and HTML. If the template file has a +.rxml+ extension then Jim Weirich’s Builder::XmlMarkup library is used. If the template file has a +.rjs+ extension then it will use ActionView::Helpers::PrototypeHelper::JavaScriptGenerator.” From Rails API
config
From its name, config directory is where the configurations files are stored, the database link file, routs and environments files. database.yml is the database link file, where we will setup our database connection settings, environment.rb is the file where we specify our application environment, remember when we talked about development, production and test databases; each one of those is related to one separate environment as well that we can run our application on.
Config directory include environments subdirectory too which include environments configurations files, for each environment a different file, to control all the environments we have the father file we’ve just talked about environment.rb.
Finally comes the routes.rb file which (as it’s named) take care of all the web requests routing in our application, starting from some very basics routes up to a very complicated ones, it is very helpful for making clean and meaningful URLs as well.
components
In this directory we can create and store components which are something like a small application with model, controller and view that we can use all over our website instead of repeating ourselves for some modules.
db
From its name, the db directory will store our database related files, earlier we used to store the SQL files that generate our database structure but now it will hold only ruby files. It will store the schema and migrations files that we will discuss after a while in this part.
When we first generate our rails application the db folder will be empty but as we move along it will contain the schema.rb file that stores our database schema definitions and a subdirectory named “migrations” to store the versioned migrations we will create.
lib
Sometimes but not always there are some code that we want to write and it doesn’t fit under any of the MVC hierarchy, such custom code will be stored in the lib directory.
public
An interesting fact about Rails that none of these directories we are talking about is viewable or accessable online except for “public“, it contains the cgi/fcgi dispatchers that will do all the underground work to deal with the routes and our application, it also contains the images, stylesheets and javascripts subdirectories that we will be calling in our views and layouts.
script
You will notice when go a little further that rails is full of generators and embedded scripts that help us along the road to generate and create many things and even run a tiny web server as well the script directory is where all these stuff are hidden.
test
The test directory is where all the automotive tests are stored, there are functional tests for our controllers with some fixtures to load and a couple of unit tests for our models as well.
vendor
As in any application, sometimes we don’t want to reinvent the wheel, we don’t want to do something that’s already done, rails as an open source framework have many wonderful plugins and resources available that we can use in our applications and we will do that as well in BookSwap, all these external libraries and plugins will be stored in the vendor directory.
doc, log, and tmp
These three directories we don’t interact with their files much as they are automatically generated and updated, the log directory will store the log files of our web server for each environment, tmp will store the session, cache and socket temporary generated files and finally doc will store the html documentation that we will generate for our application (we will cover this up in some later part).
Link The Database
After we had this quick overview over the file structure in Rails we have to configure our rails application to connect to the databases we have created earlier, the responsible configuration for this is config/database.yml which normally looks like (notice that the databases names are exactly like the one we’ve created as they follow the project name):
# MySQL (default setup). Versions 4.1 and 5.0 are recommended. # # Install the MySQL driver: # gem install mysql # On MacOS X: # gem install mysql -- --include=/usr/local/lib # On Windows: # There is no gem for Windows. Install mysql.so from RubyForApache. # http://rubyforge.org/projects/rubyforapache # # And be sure to use new-style password hashing: # http://dev.mysql.com/doc/refman/5.0/en/old-client.html development: adapter: mysql database: bookswap_development username: root password: host: localhost # Warning: The database defined as 'test' will be erased and # re-generated from your development database when you run 'rake'. # Do not set this db to the same as development or production. test: adapter: mysql database: bookswap_test username: root password: host: localhost production: adapter: mysql database: bookswap_production username: root password: host: localhost
Now for the sake of DRY ‘ing our configuration file we will change it a little bit and add our database connection details as well to:
# MySQL (default setup). defaultmysql: &defaultmysql adapter: mysql username: root password: secret #your password should be here development: database: bookswap_development <<: *defaultmysql #calling the mysql defaults test: database: bookswap_test <<: *defaultmysql production: database: bookswap_production <<: *defaultmysql
Basically what we have done is taking all the repeated information from the three database configurations parts, collect them under one reference and call this reference back in the configurations parts, by doing this we are not only DRY ‘ing our database configuration file but we also allowed different database engines to be defined more easily.
So our Rails application is linked to its blank databases using the MySQL adapter and it’s time to implement the structure we’ve decided on earlier using the rails schema and migrations facilities.
Rails + Database = Schema + Migrations
Migration in rails is the way Rails allow us to move back and forth in our application easily without losing any data from our databases but also keeping track of all the database structure changes from version to version (something like version control for our code files).
Database schema in Rails is very first database schema our rails application will have so if we want to install it on a new machine or load our database structure in any different database server it will be ready as a schema file that gets accumulated by the migrations files to move between versions.
In this part we will deal only with the schema part and later on with our versions and modifications we will get to know migrations better and have a closer look at them, now let’s generate the schema file and see how it looks like:
D:\\Projects\\Book Swap\\bookswap>rake db_schema_dump
This command will create a new file in our db folder named schema.rb, this file will hold all the starting schema setup and definitions and as this is a fresh application it will be empty from any definitions yet:
# This file is autogenerated. Instead of editing this file, please use the # migrations feature of ActiveRecord to incrementally modify your database, and # then regenerate this schema definition. ActiveRecord::Schema.define() do end
Now let’s implement the basic database schema we agreed on at the beginning of this part, three tables with few fields, after the modification our schema.rb will be like this:
# This file is autogenerated. Instead of editing this file, please use the # migrations feature of ActiveRecord to incrementally modify your database, and # then regenerate this schema definition. ActiveRecord::Schema.define() do create_table "users" do |t| t.column "fullname", :string, :limit => 80 t.column "login", :string, :limit => 80 t.column "email", :string, :limit => 60 t.column "salted_password", :string, :limit => 40 end create_table "books" do |t| t.column "title", :string t.column "author", :string t.column "publisher", :string t.column "isbn", :string end create_table "users_books" do |t| t.column "user_id", :integer, :default => 0 t.column "book_id", :integer, :default => 0 end end
If you read the above code you can easily understand that we simply created three database tables and identified their columns accordingly but notice also that we didn’t define the id column of the users and books tables, this is because ActiveRecord will create it by default.
create_table is a simple method that generates SQL code of creating a table, we used its block form to add columns of our desired type, in the block form an instance of the table definition is created as “t” and when we call t.column it’s like if we say add_column in the regular form of the create_table method.
We have a schema file that contains our database structure, we have a rails application linked correctly to our database all we have to do now is to tell rails to import this schema to the linked database:
D:\\Projects\\Book Swap\\bookswap>rake db_schema_import
(in D:/Projects/Book Swap/bookswap)
-- create_table("users")
-> 0.3440s
-- create_table("books")
-> 0.1410s
-- create_table("users_books")
-> 0.1720s
Running this command will import the database schema defined in schema.rb to our development database and that’s because the default environment of any new rails project is the development environment which can be changed and configured at anytime in config/environment.rb.
With this ruby-based database schema file we have saved ourselves from being attached to any database engine, Rails supports too many database engines like SQLite, Oracle, DB2, SQL Server and PostgreSQL, now our application can work with any of those by simply changing the connection adapter in config/database.yml file and import our schema to it using the above rake command.
This is one of the reasons why many designers or non-developers liked Ruby on Rails when they started to learn it as their first web development language and framework, Ruby has this beautiful self-explanatory code and Rails is full with Agile practices, it saved us from dealing with any SQL code and made our application cross-database-engines with Schema and Migrations.
All this read and all this steps and we didn’t see anything in action yet, maybe it’s time for us to try Scaffolding which is a quick auto-generator that we tell it about a table we want to scaffold and it will generate all the required Model, Controller and Views to connect with it and control it.
By running the following command we will be able to add, edit, delete and list all the data of our Books table:
D:\\Projects\\Book Swap\\bookswap>ruby script/generate scaffold Book Books
exists app/controllers/
exists app/helpers/
create app/views/books
exists test/functional/
dependency model
exists app/models/
exists test/unit/
exists test/fixtures/
create app/models/book.rb
create test/unit/book_test.rb
create test/fixtures/books.yml
create app/views/books/_form.rhtml
create app/views/books/list.rhtml
create app/views/books/show.rhtml
create app/views/books/new.rhtml
create app/views/books/edit.rhtml
create app/controllers/books_controller.rb
create test/functional/books_controller_test.rb
create app/helpers/books_helper.rb
create app/views/layouts/books.rhtml
create public/stylesheets/scaffold.css
This command will ask Ruby to run the scaffold generator to create the MVC setup for our table Books, the first parameter after “scaffold” is the Model/Table name and notice here that the table name here is not plural as we have specified it in our schema.rb, it’s Book not Books and this is because Rails will take care of this with it’s pluralization magic.
The second parameter in the scaffold command is the Controller/View name, basically it will create controller of the same name and a directory in the views directory named books with few templates for each action in the created controller.
Few other files got created too in the process, a helper and few test files, for now we will not deal with any of them but we can at least understand that for each data table of our database we can have all these structured files, a model to interact with the database and present the table data as objects, a controller which interact with these objects, filter them and prepare them to be viewed by the views which are templates with light embedded ruby code.
With this very minimum work, few commands and modifying a couple of files, we didn’t even write any code yet but we have something up and running and it’s time to have a sneak view on how it will look like.
D:\\Projects\\Book Swap\\bookswap>ruby script/server => Booting WEBrick... => Rails application started on http://0.0.0.0:3000 => Ctrl-C to shutdown server; call with --help for options [2006-08-20 16:49:04] INFO WEBrick 1.3.1 [2006-08-20 16:49:04] INFO ruby 1.8.4 (2005-12-24) [i386-mswin32] [2006-08-20 16:49:04] INFO WEBrick::HTTPServer#start: pid=5652 port=3000
We don’t even need to install a webserver while developing a rails application, we can simply try it with WEBrick, the simple http server bundled with rails. It will run by default on port 3000 on the localhost server so let’s check it out http://localhost:3000.

Rails welcomes us, read this page as it has some useful information that we have discussed some and will discuss the rest (routes specifically) in depth later in other parts.
So where is the magic? We have generated a scaffold for the books table and we chose the controller/view name to be books, rails understand that and it will run everything automatically under the following mapping: servername:port/controller/action, in our case the servername is localhost running on port 3000, the controller we’ve created is named books but we don’t know any action yet but let’s try this: http://localhost:3000/books/
Great!! We have a page with the title “Listing Books”, an empty table with same headers of our columns names and finally a link that says “New book”. By clicking on this link we will see something more wonderful, a ready form, lovely and simple that allows us to add new books to our database.
Let’s try filling it out with some data and add the book, where will we go next? Back to the listing page but now it’s not empty like before, we have the new book we’ve just created listed there:
What else have we got there? Three links in same row with our recently created book, Show, Edit and Destroy.. Do we have to explain? Clicking on Show will take us to a separate page that shows only the data of this particular row, Edit will take us to a form page loaded with the information of this record, ready to be edited while Destroy will popup a warning message before it will delete this record. This is it, one line only and the scaffold generator created all this for us.
Follow the URLs of each action and see how they are very meaningful and clean, all this web requests are handled in config/routes.rb as we said above, with the default route (mapping) as /:controller/:action/:id so for example if we go to http://localhost:3000/ books/show/2 routes.rb will forward this request to the books controller to run the show action on the book with 2 as its id.
Naturally scaffolding is not made to be used on its own, it’s made just to provide us with the very basics functions in a very simple way so we can understand how things work but we have to do the rest and modify the code to what perfectly suit our needs and that is what we will discuss in the next parts.
At The End
In this part we have met Rails in a little depth, had a quick look at the file structure it generates and understood some of the migrations and schema magic as well, technically we have now a basic rails application for books where we can add, edit and delete any record at any time after we wrote a very minimum amount of code and left the rest on Rails to take care of.
In the next part we will talk about creating some more tables, discussing migrations a little further and getting a better look with a nice interface and see how to implement the design with our Rails application as well, sorry for the length of this part and see you next week…
Rida Al Barazi » Blog Archive » Rails Project Story said..
[...] Getting Started: Basic Database design, implementing it through schema, introducing Rails file structure and finally scaffolding. [...]
on August 20th at 7:54 pmRami Kayyali said..
Thank you, thank you, thank you.
That was one of the most comprehensive tutorials I’ve came across.
on August 21st at 12:42 amkpumuk said..
Looks like “Aglie web development with Rails” book. Will wait for next part of story, maybe something new will be in it.
on August 21st at 2:02 pmRon said..
I’ll be back next week, I’m working on a similar app — but not books. Looks like a good start, thanks!
Ron
on August 21st at 2:59 pmRida Al Barazi » Blog Archive » Rails Project Story: 2. User Authentication said..
[...] Here comes the second part of our story, last time in part one we met rails directory structure, designed a three tables database, created it in MySQL and linked it to our application then we let rails db schema create those tables for us and finally we generated a modest scaffold for our Books table. [...]
on August 28th at 6:04 amKevin said..
Rida,
In the db schema file, how do you specify a particular type for a field? I want to speify a date type.
Thanks,
Kevin
PS: Keep up the good work on the Rails project, I very much like it so far!
on September 26th at 7:59 amKevin said..
I browsed the Rails api docs and figured it out. My problems was that I was using a limit for the :date type. Removed that, and everything worked fine.
on September 26th at 5:52 pmRida said..
Sorry Kevin for my late reply, I’m glad you found it yourself on Rails api, I was going to provide you a link there anyway ;)
on September 28th at 8:28 pmDavid said..
Hi. Love the tutorial. Looking forward to the follow-up, as I’m stuck on a simple (?) concept: scaffolding for related tables.
I have a “Team” and “Player” table for my football league. Players belong to teams, but I can’t figure out how to /player/create so that there is an auto link to a team.
on December 13th at 11:52 amOmnikorn said..
Excellent tutorial. I had been looking for a quick start in rails. Browsed many tutorials, but yours is the best.
on January 3rd at 7:24 pmdimitrisd said..
I must say that this first part, what i have read till now, is so good written that has meaning even for the complete rails beginner as i am.
on February 14th at 11:15 pmThanks!
Julia said..
Thanks! Very interestingly.
on April 30th at 1:03 pm