2. Howto make a (small) publication management app

This howto will show you how to build a RoR app a bit advanced using belongs_to, has_many and has_and_belongs_to_many and authenticate authors. This howto uses things learned in the TodoList howto, in the api doc, and in the irc channel.

This tutorial is based on rails 0.9.3

If you have the Rails gem installed, you can tie this particular program to a specific version. Go to config/environment.rb and adjust the require_gem lines like this:

require_gem 'activerecord', '>= 1.4.0'
require_gem 'actionpack', '= 1.2.0'
require_gem 'actionmailer', '<= 0.4.0'
require_gem 'rails', '= 0.9.3'

Quick description of the app

The app will allow to manage document written by authors and sorted in categories. Each document will have one author but can be sorted in many categories. Each author can have many documents, and each category to.

This howto won’t cover RoR installation there is plenty info about this in the TodoList howto and in others docs.

We will use MySQL but you can also use Postgresql or sqlite (and in these cases, please send me the sql code to create the tables).

RedCloth / Textile

This howto use RedCloth to display some textile formated text. You should install it to be able to use it too. You can install redcloth using Ruby gems :

%: sudo gem install redcloth
Restart apache and it should be ok.

Go in your work directory and use the command :

%: rails the/path/totheapp

You can use the webrick server if you want, more simple to do an howto. You just have to open a terminal and use the command (at the root of the rails app directory) :

%: ruby script/server

Then you just have to connect to http://localhost:3000 to see your app working.

If you want to use apache you have some configuration to do, look into the others howtos. I recommend you to use fastcgi.

For the present howto I’ll consider that your are using apache with a virtual host called howto. If you use the webrick server just replace the http://howto/ by http://localhost:3000/.

We’ll need 4 tables : one to store the authors, one for the documents, one for the categories, and one last (but no least) to store the links between categories and documents. So :
  • authors with the columns :
    • id : the key
    • firstname : the firstname of the author
    • name : the lastname of the author
    • nickname : the nickname, it will be used to authenticate the author
    • password : the password
    • contact : an email adress
    • description : a paragraph about the author
  • documents with the columns :
    • id
    • filename : the name of the file
    • title : the title of the document
    • description : a short paragraph to describe the document
    • date : the publication date
    • author_id : the author id. This is how ror will know how to link author and documents.
  • categories with the columns :
    • id : the key
    • name : the category name
    • description : the category descriptio,
  • categories_documents with the columns :
    • category_id
    • document_id

About the tables names

The names are not some hazardous decisions I made, there is a reason. If you correctly read the TodoList howto you know that your model name would be the name of your table singularized and with the first later capitalized, and the name of the controller will be the name of the table singularized. So we will use :
  • authors :
    • model : Author
    • controller : author
  • documents :
    • model : Document
    • controller : document
  • categories :
    • model : Category
    • controller : category

There is one important table which allow us to have a n to n relation between documents and categories. The categories_document table is where the links will be stored. The name is important by default this is what RoR will search. The word ”categories” is before the word ”documents” : categories starts with a c and documents with a d.

SQL code

Here is the MySQL dump (SQL format) :

    CREATE TABLE `authors` (
      `id` int(11) NOT NULL auto_increment,
      `firstname` varchar(50) NOT NULL default '',
      `name` varchar(50) NOT NULL default '',
      `nickname` varchar(50) NOT NULL default '',
      `contact` varchar(50) NOT NULL default '',
      `password` varchar(50) NOT NULL default '',
      `description` text NOT NULL,
      PRIMARY KEY  (`id`)
    ) TYPE=MyISAM AUTO_INCREMENT=3 ;

    CREATE TABLE `categories` (
      `id` int(11) NOT NULL auto_increment,
      `name` varchar(20) NOT NULL default '',
      `description` varchar(70) NOT NULL default '',
      PRIMARY KEY  (`id`)
    ) TYPE=MyISAM AUTO_INCREMENT=3 ;

    CREATE TABLE `categories_documents` (
      `category_id` int(11) NOT NULL default '0',
      `document_id` int(11) NOT NULL default '0'
    ) TYPE=MyISAM ;

    CREATE TABLE `documents` (
      `id` int(11) NOT NULL auto_increment,
      `title` varchar(50) NOT NULL default '',
      `description` text NOT NULL,
      `author_id` int(11) NOT NULL default '0',
      `date` date NOT NULL default '0000-00-00',
      `filename` varchar(50) NOT NULL default '',
      PRIMARY KEY  (`id`),
      KEY `document` (`title`)
    ) TYPE=MyISAM AUTO_INCREMENT=14 ;