About this entry
You’re currently reading the article “Building a RESTful Ruby on Rails Application from the Ground up with a Site-wide Layout.”
- Published:
- October 27th 04:32 AM
- Updated:
- August 17th 08:05 PM
- Sections:
- Ruby on Rails
Building a RESTful Ruby on Rails Application from the Ground up with a Site-wide Layout
In the following introductory article, I will build a stripped-down application to store a basic social graph for a person (a very fashionable subject nowadays). The steps to building the application will illustrate how to create a Rails application, configure it to connect to a MySQL database, generate resource scaffolding, use database migrations, and associate models. It will serve as a basis for later articles to illustrate more complex aspects of Rails development.
Liked it? !
Index
- Generating a Basic Application
- Creating and Configuring the Database
- Generating the Scaffold Resources
- Customizing the Database Migrations
- Associating the Models
- Setting up a Single Layout for all Controllers
- Making the Views User-friendly
- Optimizing the Application
- Testing the Application
- Related Articles
- Coming Soon
Generating a Basic Application
The first step is to generate the skeleton of the application. Run this command on your workspace folder:
rails social_graph
This will create folder called social_graph, and the whole rails structure of a new project under it.
Creating and Configuring the Database
Next, create the database that the application will use and the user that will access it. Assuming you are using mysql, you would run a sequence of commands similar to these:
mysql -u mysql-root-user -p mysql> create database social_graph_development; mysql> GRANT ALL PRIVILEGES ON social_graph_development.* TO 'rubyuser'@'localhost' IDENTIFIED BY 'rubypassword';
Configure the database and user set up above by updating the development section of social_graph/config/database.yml:
development: adapter: mysql database: social_graph_development username: rubyuser password: rubypassword host: localhost
Generating the Scaffold Resources
Now that we have laid the ground-work, we can start coding the actual application. The application will track two kinds of data: acquaintance and type of relation. For each of this, we will just generate their RESTful controllers to immediately have the basic code for creating, reading, updating, and deleting their records.
ruby script/generate scaffold_resource relation title:string description:text ruby script/generate scaffold_resource acquaintance name:string relation_id:integer description:text
This will automatically create the views, models, controllers, and migrations to the two types of data. All of these will require some tweaking.
Customizing the Database Migrations
I prefer to work with the MyISAM engine database engine (since it supports fulltext searches) and I also want to make sure that the character encoding is set to utf8. So I will add an some options to create_table in social_graph\db\migrate\001_create_relations.rb. I will also pre-populate it with three values: friend, neutral person, and enemy. The self.up method will then look something like this:
def self.up
create_table :relations, :options => 'ENGINE=MyISAM, CHARACTER SET=utf8 COLLATE=utf8_general_ci' do |t|
t.column :title, :string
t.column :description, :text
end
end
I will also add these options to the create_table method for acquaintances in social_graph\db\migrate\002_create_acquaintances.rb. The create_table section will look something like this:
create_table :acquaintances, :options => 'ENGINE=MyISAM, CHARACTER SET=utf8 COLLATE=utf8_general_ci' do |t| t.column :name, :string t.column :relation_id, :integer t.column :description, :text end
Now its time to create those tables by running the migrations:
rake db:migrate
Associating the Models
Now lets tweak the models by setting the relationship between acquaintances and relations. Since for each acquaintance we have to specify what kind of relationship it is, we included a relation_id in the table of acquaintances when creating the resource scaffold above. Using the association vocabulary, each acquaintance belongs to a relation (i.e. a person can belong to the category "friend") and each relation has many acquaintances (the category "friend" has many people it it). To reflect this association in the code, update social_graph\app\models\acquaintance.rb to
class Acquaintance < ActiveRecord::Base belongs_to :relation end
and social_graph\app\models\relation.rb to
class Relation < ActiveRecord::Base has_many :acquaintances end
Setting up a Single Layout for all Controllers
Now for the tweaking of the views. Each resource scaffold we created came with its own layout. We really don't need a layout per controller in this application. For all controllers to share the same layout will suffice. In order to do this, rename social_graph\app\views\layouts\acquaintances.rhtml to application.rhtml. Then substitute the title line:
<title>Acquaintances: <%= controller.action_name %></title>
to this more generic line:
<title><%= "#{controller.controller_name.capitalize}: #{controller.action_name}" %></title>
You can safely remove social_graph\app\views\layouts\relations.rhtml, leaving application.rhtml as the only file under the social_graph\app\views\layouts folder. All controllers from this point onward will use application.rhtml as their layout.
Making the Views User-friendly
When displaying the acquaintance info, it is pointless for the end-user if we display the relation id, as this means nothing to him. Instead we should display the title of the relation. Under social_graph\app\views\acquaintances\index.rhtml, change the line displaying the relation_id:
<td><%=h acquaintance.relation_id %></td>
to this:
<td><%=h acquaintance.relation.title %></td>
Do the same for social_graph\app\views\acquaintances\show.rhtml. Change the line displaying the relation_id:
<%=h @acquaintance.relation_id %>
to:
<%=h @acquaintance.relation.title %>
Finally for the edit, we should allow the user to choose the kind of relation he has to an acquaintance from a drop down list, rather than asking him to enter the relation_id. First we need to have all relations available from the edit view. In order to do this we need to get them from the acquaintance controller. Update the new and edit methods in social_graph\app\controllers\acquaintances_controller.rb to include the fetching of the relations:
# GET /acquaintances/new def new @acquaintance = Acquaintance.new @relations = Relation.find(:all) end # GET /acquaintances/1;edit def edit @acquaintance = Acquaintance.find(params[:id]) @relations = Relation.find(:all) end
Change the line in both the new and edit views (social_graph\app\views\acquaintances\new.rhtml and social_graph\app\views\acquaintances\edit.rhtml) from the text box asking for the relation_id:
<%= f.text_field :relation_id %>
to a dropdown list asking to select the relation from the list of titles:
<%= f.select('relation_id', @relations.collect {|r| [h(r.title), r.id] }, { :include_blank => false }) %> (<%= link_to 'New relation', new_relation_path, { :target => '_blank' } %>)
Optimizing the Application
Such a simple application does not really make use of sessions since we are not really tracking anything. To disable sessions, update the session line from social_graph\app\controllers\application.rb from
session :session_key => '_social_graph_session_id'
to
session :disabled => true
Testing the Application
We are all done with the first stage of creating a functioning application! Test it out by running the development server like this:
ruby script/server
and opening the browser to:
http://localhost:3000/acquaintances/new
Related Articles
This first article was the starting point for a series of articles describing more advanced topics. Later articles that have built on top of the social_graph application are:
- Theme support. Suppose that your Ruby on Rails application is a generic one designed to be run customized to the look and feel of each of your client's taste. You can easily make it run in several places, each instance with its own customized stylesheets, javascripts, images, layouts, and views by adding theme support to it. In this article I will show you how.
- Follow-up on theme_support and integration with rxml templates. This article gives a brief intro to rxml templates and proposes fixes to the theme_support plugin for better integration.
- View Translation - Globalizing a Ruby on Rails Application by Adding Multilingual Support to the Views. Using the globalize plug-in for Ruby on Rails out-of-the-box makes it easy to add support for various languages. It can handle the management of translated terms and translation of views (displaying the messages on each page in the selected language). This article gives a brief introduction about to how to implement view translation with globalize in an actual application.
Coming Soon
- Support for languages using complex scripts, such as Chinese, Tibetan, and Dzongkha. Globalize is great, but it falls short when the languages you want to support require specific fonts and font sizes or use Unicode ranges that may not be interpreted correctly by the browser. In this article I will show how to extend globalize to easily support these special cases.
- User management. Here I will illustrate how to implement a full login support with roles and privileges. Depending on the type of user, he will be allowed to perform certain actions.
Stay tuned!

4 comments
Jump to comment form | comments rss [?]