Beginners Guide to Rails, part 2

6 comments | Posted: 3 July 06 in Tutorials, by Robert Evans

Note: this is cross posted over at my site as well.

Welcome back to the second part of our Beginners Guide to Rails! We are going to be taking a different approach with part 2. Instead of talking about the Scaffolding magic I am going talk about specific subjects that have come up in our Ruby on Rails forum, here at Godbit, as well as a few other things pertaining to our Contact application.

There have been some requests to help better understand Migrations and I want to touch on Routing in Rails. I will also give a brief overview of implementing CSS in your Rails applications.

If you haven’t already, go to the Ruby on Rails website to see how to upgrade to Rails version 1.1.4. I am also using Ruby 1.8.4. We are going to be building off of our Contact Application that we created in the last tutorial. Well, let’s get started!

Routing

In the last tutorial, we built our scaffolding and opened our browsers to localhost:3000/people. We didn't talk about how to route our Rails application to go directly to the people controller by typing localhost:3000 in the browser. First, we need to open up the route.rb file which is located in the config folder of your Rails application. There are a couple of lines you will see in there for default routing purposes:


map.connect ':controller/service.wsdl', :action => 'wsdl'
map.connect ':controller/:action/:id'

The first map.connect has to do with Web Services and is out of the scope of this article. The second map.connect maps URL to our application code. Let's say we enter the following URL into our browser:

http://localhost:3000/people/list/1

Rails will take the piece after the domain name, people/list/1, and use that part to look inside our routing file for a match. Rails will go through each definition in the routing file until it finds a match. In this case, Rails will match our URL with the second map.connect above. People will be mapped to our first parameter, the controller; list will be mapped to the people controller's list method, and the number 1 will be mapped to our id to look up in the list method, inside our people controller. Phew, that might be a lot to take in at first, but an easy way to think of this is to take the :controller/:action/:id and invision people/list/1 taking the place, in order, of our map.connect routing definition.


map.connect '', :controller => 'people'

The single quotes after map.connect sets the default localhost:3000 to go to the people controller. To get this working, make sure to delete the index.html file found in your public directory of your Rails application and make sure to restart the Webrick server.


map.connect "*anything", :controller => 'people', :action => 'request_error'

The above can be used as a catchall for when a user enters an incorrect URL for your Rails application. Two things you need to make sure you do with the above definition: 1. make sure you add the action 'request_error' to the people's controller and 2. make sure you create your RHTML file within the people view directory (RAILS_APP/app/views/CONTROLLER_NAME/) of your Rails application. In this case, your RHTML file will be called request_error.rhtml. Inside that file, add whatever you want to be displayed, either straight HTML or using your controller and RHTML file to have something dynamic displayed.

There are many creative things you can do with routing. Rails provides maximum flexibility. These examples I have given you are some of the more simple routing techniques you can apply.

Migration

I often hear people new to Rails development say, 'What is the point to Migrations and why should I use it?' Well, it is quite simple, if you desire an agile environment and adhere to its principles, then migrations is the way to go.

To put it simply, migration is a Data-Definition Language (DDL), which is a schema in a source form (the programming language you are using) which allows version control. To simplify this even further, migrations allow your applications to scale over time, in an agile manner. If you need to add a table, alter a table, remove a table, or remove a column from your database, migrations make it dead simple. You can roll back your schema if you need to or develop it further to handle new features. Rails automatically versions or schema's by applying version numbers to it.

How does this work you ask? I'll tell ya, when you apply a new migration to a database of existing tables, such as adding an email column, Rails looks to another table called schema for a version number. Rails then compares the database schema number with the new version and if Rails finds the new version to be higher than the database schema number, Rails applies the new schema. Rails always start with the number one and then each new migration gets the next available number.

If you choose to roll back to a previous version of your schema, Rails also makes this simple. Each of your migration files contains two sets of instructions – one for updating and one for rolling back. When you roll back, Rails looks again to the version number and then rolls it back to the previous available number.

One thing to note is that whenever you create a Model, Rails will automatically create a migration file for that Model. If you would like Rails to not do this, you can add the following command to your Model generate command: --skip-migations.

Since the last tutorial, a few things have changed within Rails. One of those is how you run your migration files. In the last tutorial, I showed that you could simply type rake migrate. You would now run a migration file by typing rake db:migrate command in the command prompt.

Migration Anatomy

Each migration class file, being a subclass of the ActiveRecord class, should contain at least two class methods. The first method you need to have is the up() method. This method is responsible for applying the changes to our schema. The second method is the down() method. This method does all the undoing of the up() class method.

Migration files also declare columns to be created, updated, or deleted. These columns can be strings, integers, floating numbers, date, datetime, text, timestamp, binary, or boolean. One question that might arise is that databases don't have strings for their datatype. That being correct where the precise name is concerned, VarChar() is a string, so strings is the same as VarChar(). In the last tutorial, you saw how to apply these columns, as well as the class methods.

So far this is pretty basic stuff. So, what if we wanted to change our address column from string to text? It is actually quite simple. We would do the following:


def self.up
  change_column :people, :address, :text
end

def self.down
  change_column :people, :address, :string
end

How about if we wanted to change our column 'name' to 'first_name'?


def self.up
  rename_column :people, :name, :first_name
end

def self.down
  rename_column :people, :first_name, :name
end

How about if we wanted to rename our table 'people' to 'contacts'?


def self.up
  rename_table :people, :contacts
end

def self.down
  rename_table :contacts, :people
end

Do you see how using migrations can help create and maintain an agile development?

There is one important thing to note about renaming tables. When you do so, you will most likely have to rename your model that is associated with it. One way you wouldn't have to rename your model is by creating a dummy version of your model classes needed by the migration within the migration itself. That is out of the scope of this tutorial, but something to keep in mind if you ever decide to change the table name.

There a lot of other really cool things you can do with migrations, so much so that there are chapters in books written about just Rails migrations. Hopefully this small bit will give you a better understanding of how cool migrations are and how useful and powerful they are to your development.

Cascading Style Sheets in your Rails

CSS is very easy to add and change within your Rails application. First, we need to talk about our application layouts. You can find the layouts here: RAILS_APP/app/views/layouts/.

When we did our scaffolding call using the Rails generator, it automatically created our people.rhtml layout file. This is a bare bones file and should be altered, adding such things as Doc Type. One thing you should know, is that if you are going to have just one layout for your whole site, then name that layout application.rhtml (keep it in the same directory as the one I mentioned above) and it will be used for every controller you create, unless you specify otherwise in the controller itself. Now, let's open up that people.rhtml file in our layout folder.

In this file, you will see the following embedded Ruby code, added by Rails:


stylesheet_link_tag 'scaffold'

That tag is the same as the following:


link href="/stylesheets/scaffold.css" media="screen" rel="Stylesheet" type="text/css"

You will notice that in our Rails code the 'scaffold' is the name of the Style Sheet. You can change this name to reflect whatever style sheet you want to use. Also, this style sheet can be found in your Rails application inside public/stylesheets.

If you wanted your media to be something different, you can alter that in the Ruby code doing the following:


stylesheet_link_tag 'scaffold', :media => “all”

If you want to add more than one style sheet:


stylesheet_link_tag 'scaffold', 'core', :media => “all”

I think you will agree that it is pretty basic to work with CSS in Rails. Just alter your CSS file as you would when working outside of Rails.

Conclusion

This concludes part 2 of our Rails Beginner series. You should have a better understanding of Routing, Migrations and how easy it is to work with Style Sheets in Rails. In our next tutorial, I am open to suggestions on various topics to cover. Go ahead and leave a comment on what you would like to see/learn next and I will see what I can do. Either in the next tutorial or an upcoming one, I will be writing about the somewhat new Remote Javascript that came out with Rails 1.1. It really makes adding Javascript and Ajax even easier.

Also, I wanted to apologize for the long length of time in getting this tutorial out to you all. I will make every attempt to get the next tutorial out quicker. Take care and God Bless!

Download the complete tutorial file | Contact Application

Discuss This Topic

  1. 1 Yannick

    Thanks for another good tutorial Robert. I’d be interested in seeing a bit more of adding javascript/ajax in Rails.

     
  2. 2 John

    Thanks for the article. I have a question about migration though:

    Say I coded a change column name:
    rename_column :people, :name, :first_name

    Does Rails also change all of the controllers and models code from ‘name’ to ‘first_name’? Or, do I need to manually change the application code to reflect the new column name?

     
  3. 3 John

    Also, I wanted to ask, how does one create indicate the primary key or constraint when coding a create table in an up() method?

     
  4. 4 Ryan

    John,

    The primary key is created automatically when you use migrations. Unless you specify otherwise, the primary key will always be called “id”. You can disable the creation of a primary key by passing :id => false.

    See

    * http://wiki.rubyonrails.org/rails/pages/ActiveRecordMigration
    * http://wiki.rubyonrails.org/rails/pages/UnderstandingMigrations
    * http://wiki.rubyonrails.org/rails/pages/UsingMigrations

     
  5. 5 Brandon

    Can you direct me to the first part of this tutorial… thanks

     
  6. 6 Robert

    John: You need to manually change the column names.

    As Ryan said, Rails creates the primary key for you.

    Brandon: http://godbit.com/article/beginners-guide-to-rails-part-1

     

Comments closed after 2 weeks.