RSS Feed
Download our iPhone app
Browse DevX
Sign up for e-mail newsletters from DevX


Build a Wiki System with Rails : Page 3

Learn how to build a simple, file-based Wiki system using the Ruby on Rails web application framework. You won't believe how easy it is.

Developing the "Model" Class
Since Rails is typically used to develop database-backed web applications, most developers working with such applications typically use the script/generate command to generate the model and related files. However, since this example uses file-based persistence, you will write your model class from scratch (see Listing 1) while still following as many of the Rails conventions as possible. For example, you will place your model class, Wiki, in the app/models directory (as app/models/wiki.rb) where Rails would normally place generated model files. Furthermore, the method naming conventions are similar to those found in the ActiveRecord::Base class provided by Rails. Listing 1 shows the complete Wiki model class.

A few of the notable methods in this class include basedir, find, find_wikis, and save, so let's take a closer look at these methods:

  • The basedir method allows you to set a static directory name where all the Wiki files will be stored. If this method is not called, then the current directory is used by default as specified in the class variable @@basedir.
  • The find method reads in an entire Wiki file and returns it as a string to the caller. (While find as a method name might sound a bit misleading since it reads in a file, I chose this name to stay consistent with the Rails naming convention. By following similar naming conventions, you should be able to switch to a database-based persistence model easily using the Rails model support.)
  • The find_wikis method returns an array of file names found in basedir ending with the value of the class variable @@extension, which in this case happens to default to ".Wiki".
  • The save method simply opens a file for writing and writes the entire contents of the method parameter content to it.

The other notable public methods include delete, exists?, and attributes. The delete method deletes a Wiki file, the exists? method indicates whether a Wiki file exists or not, and the attributes method provides attributes of a file (such as modified date and file size).

Unit Testing the Model Code
Before plugging the model code into your controller class, you should unit test it to ensure all its methods work as advertised. Generally, using small unit tests that test individual methods is advisable, but I chose to put multiple tests in a single method named test_wiki in the unit test file test/unit/wiki_test.rb. The test_wiki method tests the save, find, delete and exists? methods in the Wiki model class, as shown in the following code excerpt from the wiki_test.rb file:

# Ensure file doesn't exist (yet)      
assert !File.exists?(getfullpath(@filename))

# Test save and find
Wiki.save @filename, DEFAULT_TEXT
assert File.exists?(getfullpath(@filename))
text = Wiki.find(@filename)
assert_equal DEFAULT_TEXT, text
# Test delete
Wiki.delete @filename
# Test exists?
assert !Wiki.exists?(@filename)

You should be aware of a couple of problems—and their corresponding solutions—related to testing database-less rails applications. You typically would unit test the model classes by typing the command rake test:units (rake test_units in previous versions of rails) from the top-level directory of a Rails application. However, since Rails tries to connect to the database by default and the RailsWiki application isn't using a database, you need to make two changes to get this to work (thanks to the "Ruby on Rails Unit Tests" blog by Jay Fields).

First, you need to include a file under lib/tasks ending with the extension .rake. Accordingly, in the downloadable source code for this article, you will find a file named testing.rake. This file must contain the following line of Ruby code:


Secondly, you need to fix the test/test_helper.rb file by replacing its code with the following:

ENV["RAILS_ENV"] = "test"
 require File.expand_path(File.dirname(__FILE__) \
          + "/../config/environment")
 require 'application'
 require 'test/unit'
 require 'action_controller/test_process'
 require 'breakpoint'

Now running the command rake test:units will generate output similar to this:

Finished in 0.094 seconds.

1 tests, 5 assertions, 0 failures, 0 errors

Close Icon
Thanks for your registration, follow us on our social networks to keep up-to-date