Improved Scaffolding for Ruby on Rails
Rails can help with the creation of our database tables, and we need three: one to hold information on our soccer players, another for squad data and another to maintain medical conditions. For the sake of simplicity, let's assume that each player belongs to one squad and can have a single medical condition (or none at all). Let's tell Rails about the tables:
ruby script/generate model player ruby script/generate model squad ruby script/generate model condition
Models in Rails let us talk to our data from our Web application. Each of the above commands produces eight lines of output while Rails does its thing. Note that each contains a file generated in the db/migrate directory. These are our database migrations. At this point, things get less SQL-centric and more Rails-like, as Rails provides a database-independent way to define our tables. To see this in action, edit the db/migrate/xxxxxxxxx_create_players.rb file (where xxxxxxxxx is a unique date/time string generated by Rails), changing the self.up method to look like this:
def self.up create_table :players do |t| t.integer :squad_id, :condition_id t.string :name, :address, :contact_tel_no t.date :date_of_birth t.timestamps end end
This is the high-level Rails way of telling your database to create a table. Each column in the table gets a unique name and a data type. Note that in addition to the columns you might expect each player to have (name, address and so on), we add in two integer columns that will link to the squad and condition tables. What's cool about using migrations is that it does not matter which database you are using, Rails generates the correct database-specific SQL statements as required and when needed. Let's define the other two tables. Edit db/migrate/xxxxxxxxxx_create_squads.rb, changing the self.up method as follows:
def self.up create_table :squads do |t| t.string :name t.timestamps end end
And, finally, change db/migrate/xxxxxxxxxx_create_conditions.rb to have a self.up method that looks like this:
def self.up create_table :conditions do |t| t.string :name t.timestamps end end
Now for the fun part, type the following at the command-prompt:
Output similar to the following should scroll by on screen:
(in /home/barryp/rails/soccer_club) == CreatePlayers: migrating ===================== -- create_table(:players) -> 0.1916s == CreatePlayers: migrated (0.1918s) ============ == CreateConditions: migrating ================== -- create_table(:conditions) -> 0.0183s == CreateConditions: migrated (0.0185s) ========= == CreateSquads: migrating ====================== -- create_table(:squads) -> 0.0309s == CreateSquads: migrated (0.0311s) =============
What's happened is that Rails has connected to the back-end database and created the three required tables. Note that there's no programmer-written SQL code in sight! Rails handles all the down-and-dirty SQL details. For those readers who don't believe me, log in to PostgreSQL as soccer_manager and bask in the glory of the table schema that Rails has created for you.
At this point, it would be normal to use Rails to generate some scaffolding code, then reach for a CSS reference to pretty up the whole thing. This is doable, but it takes time. For now, let's use Rails to generate empty controllers with these three commands:
ruby script/generate controller player ruby script/generate controller squad ruby script/generate controller condition
Each of these commands produces seven lines of output. Note that a Ruby file is generated in the app/controllers directory. These are source code files that will contain any business logic we want to add to our Rails application. We will do this in a little while. To complete the default Rails setup, we need to specify our table relationships. Edit app/models/player.rb to look like this:
class Player < ActiveRecord::Base belongs_to :condition belongs_to :squad end
ActiveScaffold is written and maintained by a dedicated group of Rubyists who live at activescaffold.com/team. ActiveScaffold is a Rails plugin, and as such, gets installed into an existing Rails project, so let's do that first. From the top-level directory of your Rails application, type the following (which should be entered on a single line):
git clone git://github.com/activescaffold/active_scaffold.git \ vendor/plugins/active_scaffold && \ rm -rf vendor/plugins/active_scaffold/.git
This command fetches ActiveScaffold and installs it into your Rails application. When this process completes, a new directory has been created within the vendor/plugins/ directory of your Rails application called activescaffold. For the plugin to work its magic, we need to create an application-level layout that will be used throughout our Rails application. Here's a bare-bones layout, which we need to create in the app/views/layouts directory and which is called application.rhtml:
class PlayerController < ApplicationController active_scaffold :player end
Add a similar line of code to the app/controllers/squad_controller.rb and app/controllers/condition_controller.rb files, then start your Rails application:
Fire up your browser and load the http://localhost:3000/player page. Take a look at Figure 1, which shows the default ActiveScaffold player listing—it looks great. Note that ActiveScaffold has spotted the links between the three tables and pulled in the appropriate data values. Note also that I've added some sample data to my Web app. Unfortunately, the ordering of the columns leaves a little to be desired, and this is no more evident than when we view the default ActiveScaffold player form, as shown in Figure 2. This form displays the table columns in alphabetical order, which is not what we want. In addition, the subforms that provide access to the squad and medical condition data are cool, but what we want is a simple drop-down list for our application. Thankfully, adjusting ActiveScaffold's default behaviors is not difficult, as we shall see in a few moments.
Another problem (which you may have noticed if you've been following along) is that the date range associated with the date_of_birth value is very restrictive, using 1997 as the earliest start year. As all of our soccer players were born in the early 1990s, we need some way to adjust the start year for any entered dates. ActiveScaffold (together with Rails) can help here too.
Free DevOps eBooks, Videos, and more!
Regardless of where you are in your DevOps process, Linux Journal can help!
We offer here the DEFINITIVE DevOps for Dummies, a mobile Application Development Primer, and advice & help from the expert sources like:
- Linux Journal
Web Development News
- Android Candy: Google Keep
- Readers' Choice Awards 2014
- Handling the workloads of the Future
- How Can We Get Business to Care about Freedom, Openness and Interoperability?
- Days Between Dates?
- Synchronize Your Life with ownCloud
- diff -u: What's New in Kernel Development
- Computing without a Computer
- December 2014 Issue of Linux Journal: Readers' Choice