At the Forge - Ruby on Rails

Explore a Web development framework that comes with its own Web server, magically keeps track of details for you and integrates new code without restarting.
Customizing the Behavior

Now that we know how to see the default message, let's move toward a “Hello, world” program. In Rails, there are two basic ways to do this. We can create a controller that returns HTML to the user's browser, or we can create a view that does the same. Let's try it both ways, so that we can better understand the relationship between controllers and views.

If all we want to do is include a simple, static HTML document, we can do so in the public directory. In other words, the file blog/public/foo.html is available under WEBrick—started by executing blog/script/server—at the URL /foo.html.

Of course, we're interested in doing something a bit more interesting than serving static HTML documents. We can do that by creating a controller class and then defining a method within that class to produce a basic “Hello, world” message. Admittedly, this is a violation of the MVC separation that Rails tries to enforce, but as a simple indication of how things work, it seems like a good next step.

To generate a new controller class named MyBlog, we enter the blog directory and type:

ruby script/generate controller MyBlog

Each time we want to create a new component in our Rails application, we call upon script/generate to create a skeleton. We then can modify that skeleton to suit our specific needs. As always, Rails tells us what it is doing as it creates the files and directories:

exists  app/controllers/
exists  app/helpers/
create  app/views/my_blog
exists  test/functional/
create  app/controllers/my_blog_controller.rb
create  test/functional/my_blog_controller_test.rb
create  app/helpers/my_blog_helper.rb

Also notice how our controller class name, MyBlog, has been turned into various Ruby filenames, such as app/views/my_blog and app/helpers/my_blog_helper.rb. Create several more controller classes, and you should see that all of the names, like FooBar, are implemented in files with names like foo_bar. This is part of the Rails convention of keeping names consistent. This consistency makes it possible for Rails to take care of many items almost magically, especially—as we will see next month—when it comes to databases.

The controller that interests us is my_blog_controller.rb. If you open it up in an editor, you should see that it consists of two lines:


class MyBlogController < ApplicationController
end

In other words, this file defines MyBlogController, a class that inherits from the ApplicationController class. As it stands, the definition is empty, which means that we have neither overridden any methods from the parent class nor written any new methods of our own. Let's change that, using the built-in render_text method to produce some output:


class MyBlogController < ApplicationController

  def hello_world
render_text "Hello, world"
  end

end

After adding this method definition, we can see its results by going to http://192.168.2.3:3000/MyBlog/hello_world.

Notice how the URL has changed: static items in the public directory, such as our file foo.html, sit just beneath the root URL, /. By contrast, our method hello_world is accessed by name, under the controller class that we generated. Also notice that we did not need to restart Rails in order to create and test this definition. As soon as a method is created or changed, it immediately is noticed and integrated into the current Rails system.

If we define an index method for our controller class, we can indicate what should be displayed by default:


class MyBlogController < ApplicationController

  def hello_world
render_text "Hello, world"
  end

  def index
render_text "I am the index!"
  end

end

Of course, it's not that exciting to be able to product static text. Therefore, let's modify our index method such that it uses Ruby's built-in Time object to show the current date and time:


def index
    render_text "The time is now " + Time.now.to_s + "\n"
end

And voil� As soon as we save this modification to disk, the default URL (http://192.168.2.3:3000/MyBlog/, on my computer) displays the time and date at which the request was made, as opposed to a never-changing “Hello, world” message.

Let's conclude this introduction to Rails by separating the controller from its view once again. In other words, we want to have the controller handle the logic and the view handle the HTML output. Once again, Rails allows us to do this easily by taking advantage of its naming conventions. For example, let us modify our index method again, this time removing its entire body:

def index
end

This might seem strange at first glance. It tells Rails that the MyBlog controller class has an index method. But it doesn't generate any output. If you attempt to retrieve the same URL as before, Rails produces an error message indicating that it could not find an appropriate template.

Because the template is a view, we can define it inside of the blog/app/views directory of our application. And because we are defining the index view for the MyBlog class, we modify the index.rhtml file in the my_blog subdirectory of views. Notice how Rails turns ThisName into this_name when it comes to directories. Doing so saves users from having to think about capitalization in URLs, while staying consistent with traditional Ruby class naming conventions.

.rhtml files are a Ruby version of the same kind of template that you might have seen before. It acts similarly to ASP and JSP syntax, with <% %> blocks containing code and <%= %> blocks containing expressions that should be interpolated into the template. However, nothing stops us from creating an .rhtml template that actually is static:


<html>
<head>
<title>
    Hello, again!
</title>
</head>

<body>
<p>Hello, again!</p>
</body>

</html>

Consider what happens now if you attempt to load MyBlog in your browser. The controller class MyBlog is handed the request. Because no method was named explicitly, the index method is invoked. And because index doesn't produce any output, the my_blog/index.rhtml template is returned to the user.

Finally, let's take advantage of our template's dynamic properties to set a value in the controller and pass that along to the template. We modify our index method to read:

def index
  @now = Time.now.to_s
end

Notice how we have used an @ character at the beginning of the variable @now. I found this to be a little confusing at first, as @ normally is used as a prefix for instance variables in Ruby. But it soon becomes fairly natural and logical after some time.

Finally, we modify our template such that it incorporates the string value contained in @now:


<html>
<head>
<title>
    Hello, world!
</title>
</head>

<body>
<p>Hello, world!</p>
<p>It is now <%= @now %>.</p>
</body>

</html>

Once again, you can retrieve the page even without restarting Ruby. You should see the date and time as kept on the server, updated each time you refresh the page.

______________________

Comments

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.

Minor adjustment to URL

goblin's picture

Hi,

This URL didn't work in my case:
http://192.168.2.3:3000/MyBlog/hello_world
- it just produced an error:

Routing Error
Recognition failed for "/MyBlog/hello_world"

Instead, I had to use:
http://192.168.2.3:3000/my_blog/hello_world
- which produced the desired result.

goblin

Standort-Marketing-Tool on ruby?

Standort Marketing's picture

We thought about running our new standort-informations-system on ruby, so i came to this site... Big thanks for the information!

Ruby on Rails

John's picture

Thanks for a great introduction to Ruby on Rails. This was perfect to wet my appetite and help me with my ruby and rails installation! I am going on to read the follow-on articles!

Ruby explained in a funny video

Webdesign Hamburg's picture


http://www.rubyonrails.com/media/video/rails_take2_with_sound.mov

This is a very nice movie, where you can see them installing a weblog runned ruby in 15 minutes. its fun!

White Paper
Linux Management with Red Hat Satellite: Measuring Business Impact and ROI

Linux has become a key foundation for supporting today's rapidly growing IT environments. Linux is being used to deploy business applications and databases, trading on its reputation as a low-cost operating environment. For many IT organizations, Linux is a mainstay for deploying Web servers and has evolved from handling basic file, print, and utility workloads to running mission-critical applications and databases, physically, virtually, and in the cloud. As Linux grows in importance in terms of value to the business, managing Linux environments to high standards of service quality — availability, security, and performance — becomes an essential requirement for business success.

Learn More

Sponsored by Red Hat

White Paper
Private PaaS for the Agile Enterprise

If you already use virtualized infrastructure, you are well on your way to leveraging the power of the cloud. Virtualization offers the promise of limitless resources, but how do you manage that scalability when your DevOps team doesn’t scale? In today’s hypercompetitive markets, fast results can make a difference between leading the pack vs. obsolescence. Organizations need more benefits from cloud computing than just raw resources. They need agility, flexibility, convenience, ROI, and control.

Stackato private Platform-as-a-Service technology from ActiveState extends your private cloud infrastructure by creating a private PaaS to provide on-demand availability, flexibility, control, and ultimately, faster time-to-market for your enterprise.

Learn More

Sponsored by ActiveState