forum tutorial

In this tutorial, we will build a forum application from scratch from the standpoint of a developer working for a stakeholder. In each portion of the tutorial we'll be given a set of requirements and incrementally meet each requirement. 

The first set of requirements are:

  1. The first page the user sees should contain a list of forums
  2. Each forum should have a name and a description
  3. The forum name should be at least 10 characters
  4. The forum description should be 500 characters or less
  5. The url for each forum should contain the forum name

Step 1

The first requirement is not something we can do right now, but we can get to it shortly. For now lets start with the second requirement. Each forum should have a name and a description. That's enough information to build our Forum class.

  rails new forum_app
  rails g scaffold forum name:string description:text
  rake db:migrate

Step 2

Now we can make sure that the first page the user sees is a list of forums. Each class has an index action in the controller. The index page contains a list of all instances of each class. All we need to do is set this as the default page for the forum application. This is easy to do- all we need to do is set it up in config/routes.rb.

You can read about routes here http://guides.rubyonrails.org/routing.html

config/routes.rb

  root :to => "forums#index"

Step 3

Next we need to make sure that each forum has a name that is at least 10 characters long. We can control the behavior of each class in the model and that's where business logic such as this belongs. Active Record has built in helpers called validations. You can read about validations here, http://guides.rubyonrails.org/active_record_validations_callbacks.html

app/models/forum.rb

validates :name, :presence => true,
                   :length => {:minimum => 10}

Step 4

Limiting the maximum number of characters that an attribute can have is just as easy. And while it wasn't a requirement, we'll make sure that each forum has to have a description anticipating that it would be a requirement in the future.

app/models/forum.rb

validates :body, :presence => true,
            :length => {:maximum => 250}

Step 5

The next requirement might seem a little tricky, but it is actually straightforward. Normally, the url to each object contains the primary id of the object. To override this, we simply override the to_param in the model to use whatever attribute we wish. However, using the name attribute would be a bad idea. Each object's name can be edited and if this happens then the url would change. This would make it hard for people to link to our forum. What we'll do is create a new attribute, permalink. 

rails g migration add_permalink_to_forums permalink:string

Don't migrate yet, we need to edit the migration.

Step 6

Before we migrate the database we're going to edit the migration. We need to make sure that looking up an object by its permalink attribute is quick and easy. To do this, we need to create an index on the permalink attribute. A general rule of thumb is to add an index if ANY search will be based on the attribute. Remember to run the migration after we edit it.

db/migrate/add_permalink_to_forums.rb

def self.up
  add_column :forums, :permalink, :string
  add_index :forums, :permalink, :unique => true
end

Step 7

Now that we have the permalink attribute setup, we need to build it each time a forum is created. Luckily there is a before_create filter that we can use to set the value for this attribute before it is saved.

app/models/forum.rb

before_create :create_permalink
private
def create_permalink
  permalink = self.name.gsub(' ', '-').gsub(/[^a-zA-Z0-9\_\-\.]/, '')
  self.permalink = permalink
end

Step 8

With the permalink value in place we need to use it to find forum objects. This means we need to override the to_param in the forum model and find_by_permalink in the forum controller.
app/models/forum.rb

def to_param
  permalink
end

In the forums controller change each instance of find to find_by_permalink.

@forum = Forum.find_by_permalink(params[:id])

Step 9

That's it! The requirements are all fulfilled. We'll add more functionality in the next forum tutorial.

If you get stuck you can view the full code here, https://github.com/rhuberdeau/forum-tutorial