I originally wrote this article for fifth issue of Rails Magazine. In addition to print version, you can download all issues of Rails Magazine in pdf for free. Not only that, they also allow authors to self-publish their articles on blogs etc. after 30 days of issue release. I hope rails beginners will particularly find this post useful.

In this two-part series, I will trying to explain Active Scaffold from the ground up using a real world example.

Introduction

ActiveScaffold is a rails plugin that generates an ajaxified management interface based on the database tables.  It is an incredibly powerful, configuration-driven framework that automatically provides all CRUD operations. It is easily and highly configurable. Let us have a walkthrough of active scaffold with details on configurability and customization options it provides using a sample application. The demo application which we are going to develop is a management site for a sports club.

Configuration

Here our example is about building an administration panel for a sports club “mysportsclub”. It consists of sports, players, coaches and equipments. There are various kinds of sports in the club. Each player can have membership for any number of sports. Each sport will have one trained coach for guidance and various equipments which will be issued to the players. Let’s begin with the implementation of “mysportsclub”

Let’s setup our rails application “mysportsclub”. Run the following commands:

rails mysportsclub

Install the latest version of the plugin which is compatible with latest stable rails (2.3.x):

script/plugin install git://github.com/activescaffold/active_scaffold.git

Note: Latest active scaffold version works only with rails version higher than 2.2. Also, install render_component plugin since it is now removed from rails 2.3 but used by active scaffold.

Layout:

This is the standard active scaffold layout admin.html.erb:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
       "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
<head>
   <title>My Sports Club</title>
   <%= javascript_include_tag :defaults %>
   <%= active_scaffold_includes %>
</head>
<body>
   <%= yield %>
</body>
</html>

Model/Migrations:

script\generate model sport name:string description:text coach_id:integer
script\generate model player name:string date:birth_date
script\generate model equipment name:string sport_id:integer
script\generate model coach name:string
script\generate model players_sport player_id:integer sport_id:integer

rake db:migrate

Add the following code to the respective models. This code defines the associations for the various models:

sports.rb

class Sport < ActiveRecord::Base
  belongs_to :coach
  has_many	:equipments, :dependent => :destroy

  has_many	:players_sports, :dependent => :destroy
  has_many	:players, :through	=> :players_sports

  validates_presence_of	:name
  validates_uniqueness_of	:name
end

coach.rb

class Coach < ActiveRecord::Base
  has_one	:sport
  validates_presence_of	:name
end

player.rb

class Player < ActiveRecord::Base
  has_many	:players_sports, :dependent => :destroy
  has_many	:sports, :through	=> :players_sports

  validates_presence_of	:name
end

equipment.rb

class Equipment < ActiveRecord::Base
  belongs_to	:sport
  validates_presence_of	:name
end

players_sport.rb

class PlayersSport < ActiveRecord::Base
  belongs_to	:player
  belongs_to	:sport
end

Note I

Don’t forget to add the plural form of “equipment” as “equipments” in the config/intializers/inflections.rb.

 ActiveSupport::Inflector.inflections do |inflect|
   inflect.plural "equipment", "equipments"
 end

Active Scaffold will throw an exception if we do not define the above inflection rule.  The controller generated for the ‘Equipment’ model will be ‘EquipmentsController’. But since active scaffold generates the controller name automatically using its inbuilt function: “active_scaffold_controller_for(class_name_of_the_model)”. It will not be able to guess the correct controller name and would throw an exception while we try to access the nested equipments:

Controllers:

script\generate controller sports
script\generate controller coaches
script\generate controller equipments
script\generate controller players

Add the following code to your controllers:

sports_contrpller.rb

class SportsController < ApplicationController
  active_scaffold :sport do |config|
    config.columns = [:name, :description, :coach, :equipments]
  end
end

coaches_controller.rb

class CoachesController < ApplicationController
  active_scaffold :coach do |config|
    config.columns = [:name, :sport]
  end
end

players_controller.rb

class PlayersController < ApplicationController
  active_scaffold :player do |config|
    config.columns = [:name]
  end
end

equipments_controller.rb

class EquipmentsController < ApplicationController
  active_scaffold :equipment	do |config|
    config.columns = [:name, :sport]
  end
end

players_sports_controller.rb

class PlayersSportsController < ApplicationController
  active_scaffold :players_sport do |config|
    config.columns = [:sport, :player]
  end
end

routes.rb

map.root :controller => 'sports', :action => 'index'

map.resources :sports, :active_scaffold => true
map.resources :players, :active_scaffold => true
map.resources :players_sports, :active_scaffold => true
map.resources :coaches, :active_scaffold => true
map.resources :equipments, :active_scaffold => true

The above code will generate a complete interface for our club.

Following code for your layout will provide a navigation bar in your view.

admin.html.erb

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
    <%= stylesheet_link_tag 'admin.css' %>
    <%= javascript_include_tag :defaults %>
    <%= active_scaffold_includes %>
    <title><%= "Admin" %></title>
  </head>
  <body>
    <div>
      <div>
        <h2>Agent Website Admin Panel</h2>
        <div>
          <ul class="links">
            <li>
              <%= link_to 'Sports', sports_path %>
            </li>
            <li>
              <%= link_to 'Players', players_path %>
            </li>
            <li>
              <%= link_to 'Coaches', coaches_path %>
            </li>
            <li>
              <%= link_to 'Equipments', equipments_path %>
            </li>
            <li>
              <%= link_to 'PlayersSports', playerssports_path %>
            </li>
          </ul>
          <div class="clear">
          </div>
        </div>
      </div>
      <div id="content">
        <div id="main">
          <%= yield %>
        </div>
      </div>
    </div>
  </body>
</html>

There are various customization options available. As per our requirement we can customize the columns, links, fields, actions etc. We would discuss them in the concluding part of the series.

Payal Gupta is working working as software engineer with Vinsol. She has over two years of industry
experience.

Share this:

Privacy Preference Center