Magical, RESTful, Cruddy Rails For Seasoned Developers

I'm lazy. I admit it, and I enjoy it. But that laziness sometimes gets me into trouble, because it's combined with a healthy dose of curiosity. I can spend months exploring programming techniques, trying to find the most optimal path from start to finish, without actually digging in and implementing so much as a single line of original code. It's a form of procrastination, and yes, I am discussing it with my psychiatrist.

Regardless, sometimes the result of all this technical navel-gazing can be worth the apparently wasted time. In this case, I'm pleased to report that I have developed a streamlined configuration process for Rails applications which takes one directly from a nicely normalized database model to a working application with almost no coding.

What's so great about that? Well, it lets a developer put aside a lot of the ego and stress when approaching a new project, and get a working model with complex interactions up and running. The result may not be optimal, but it provides a much richer scaffolding on which to drape decorative CSS, RJS, and other frills. Heck, you might even spend some time doing real user testing for the interface!

Now please understand that I'm not going to go through every step here in complete detail. This is a walk through aimed at Rails developers who know the basics and want to jump into new projects a little more rapidly. There are plenty of excellent beginner tutorials you can explore to learn how to configure a basic Rails application. At the end of this article is a resources section where the creators of the custom tools I use have gone into much more detail about how their modifications work. I'm going to assume that you're already far enough along in Ruby and Rails that you have:

  1. A working Ruby interpreter

  2. A working Rails installation

  3. A compatible, accessible database

  4. An editor or IDE that you like to work with

  5. Experience setting up and testing a very basic database-backed Rails application

Getting Started

The first thing to do, as with any Rails application, is to create your application. This is done the usual way, by issuing the rails command in the directory where you want your files kept:

rails example

Set up your database connections the usual way in the application's config/database.yml file. Note that if you're using MySQL, you will need to create the appropriate databases before issuing the migration commands recommended below.

EDGE Rails

For this all to work smoothly, you must be using an installation of Rails which supports Simly RESTful models. You can install the Simply Restful plugin, but for my money, the best way to do this (circa mid-2006) is by freezing Edge Rails into your application. This has the added advantage of locking your code in at a specific version, so you can count on everything that works today working in two weeks, or two years. In your terminal, navigate to your application directory, and issue the following command:

rake rails:freeze:edge

Magic Models

The question I always had when I started a new Rails project was why I spent all that energy designing a clean, normalized database, just to recreate the entire structure with awkward belongs_to and has_many statements in my models. Thankfully, Dr. Nic has come up with Magic Models, a way that Rails can determine the intended relationships among my consistently-formatted database tables automatically.

To download the Magic Models gem, issue the following command from the command line:

gem install dr_nic_magic_models

Then, from within your Rails application's config directory, add the following line to the config/environments.rb file:

require 'dr_nic_magic_models'

Crud

The scaffolding built into Rails is still not quite up to the task of supporting truly RESTful projects yet. happily, there are a few projects out there aimed at helping a developer create clean CRUD scaffolding. The one I favor is called Crudgenerator2, an evolution of Crudgenerator. To install the plugin, issue the following command (on one line, of course):

script/plugin install http://crudgenerator2.googlecode.com/svn/trunk/crud_generator2

RESTful Data Models

Now it's up to you to design your database. Stick with normalized data models, and keep the conventions of Rails in mind, and you won't have to write any relationship configuration into your models. Make sure that any many-to-many associations are implemented as many-to-one and one-to-many associations with a separate table for the transaction type. Is that clear? Maybe I should elaborate.

For example, instead of a users table with many tags related to a tags table with many users, create a separate "taggings" table to moderate the relationship. A user may have many taggings, and a tag may have many taggings, but each tagging only relates one user and one tag. Your users table will have a field for tagging_id, your tags table will have a field for tagging_id, and your tags table will have fields for user_id and tag_id. Get the idea? No many-to-many relationships in the database, and none to represent in the data model.

Once you've decided on what models you need, all you have to do is use the newly-installed crud generator from inside your application directory to create a versatile structure of controllers, views, models, and tests for each of the models you have decided to use:

script/generate crud User
script/generate crud Tag
script/generate crud Tagging

To make the crudgenerator2 work, you also need to add the following line near the top of your application's config/routes.rb file, including a symbol for each of the models you generated. Be sure it's the first executed line in the definition, since this file is interpreted from top to bottom:

map.resources :users, :tags, :taggings

From here, you can go on to add your foreign key fields, along with any other fields you desire, to the appropriate YAML-formatted migration files which the crud generator created in your application's db directory. Once that's done, just issue the usual migrate command to generate your database:

rake db:migrate

What Next?

What you have now is a Rails app with a completely RESTful scaffolding, ready for you to tweak the views and add any custom logic you desire. All the relationships among the models are preconfigured. All the model, test, controller, and view/partial files have been created. All the database setup is built into the migration files for versioning support.

You have written the bare minimum of original code, and you have something pretty complete and ready to be played with. Cool, huh?

Resources: