The Code Behind This Site

Hosting

Every site needs hosting.

I picked:

http://www.joyent.com/

FreeBSD 5.4

The shared hosting account I use runs on FreeBSD.

Here is some information about the specific version:


[bikle@bsdbox ~]$
[bikle@bsdbox ~]$
[bikle@bsdbox ~]$ uname -a
FreeBSD bsdbox 5.4-STABLE FreeBSD 5.4-STABLE #0: Sun Oct 23 20:24:16 GMT 2005     root@mother:/usr/obj/usr/src/sys/TEXTOVERDRIVE  i386
[bikle@bsdbox ~]$
[bikle@bsdbox ~]$
[bikle@bsdbox ~]$

MySQL

Most Rails sites need a database.

The database available to me on this shared hosting account is MySQL.

Here is some information about the specific version:


[bikle@bsdbox ~]$ mysql --version
mysql  Ver 14.7 Distrib 4.1.18, for portbld-freebsd5.4 (i386) using  4.3
[bikle@bsdbox ~]$

Install Ruby

I installed ruby in my home directory.

The source code looks like this:


-rw-r--r--  1 bikle  bikle  3956902 Aug 28 21:04 ruby-1.8.6-p287.tar.bz2

I obtained it from here:

ftp://ftp.ruby-lang.org/pub/ruby/1.8/ruby-1.8.6-p287.tar.bz2

While looking for it, I found these pages to be useful:

To install Ruby 1.8.6 under my home directory, I ran these shell commands:


mkdir ~/r/
mkdir ~/tmp/
cd    ~/tmp/
wget ftp://ftp.ruby-lang.org/pub/ruby/1.8/ruby-1.8.6-p287.tar.bz2
tar jxf ruby-1.8.6-p287.tar.bz2
cd ruby-1.8.6-p287
./configure --prefix=/home/bikle/r
make
make install

Next, I prepended ~/r/bin to the beginning of my PATH-env-variable in my .bashrc file.

Then I typed in bash and then checked the version:


[bikle@bsdbox ~/software/tmp/ruby-1.8.6-p287]$
[bikle@bsdbox ~/software/tmp/ruby-1.8.6-p287]$ which ruby
/home/bikle/r/bin/ruby
[bikle@bsdbox ~/software/tmp/ruby-1.8.6-p287]$
[bikle@bsdbox ~/software/tmp/ruby-1.8.6-p287]$ ruby --version
ruby 1.8.6 (2008-08-11 patchlevel 287) [i386-freebsd5.4]
[bikle@bsdbox ~/software/tmp/ruby-1.8.6-p287]$
[bikle@bsdbox ~/software/tmp/ruby-1.8.6-p287]$

Install RubyGems

RubyGems is a utility to help us carry around modular sections of software called gems.

Once you install RubyGems, you access its functionality via the "gem" shell command.

I obtained RubyGems from here:

http://rubyforge.org/frs/?group_id=126

The source code looks like this:


-rw-r--r--   1 bikle  bikle   246920 Aug 28 21:43 rubygems-1.2.0.tgz

To install RubyGems I ran these shell commands:


cd    ~/tmp/
wget http://rubyforge.org/frs/download.php/38646/rubygems-1.2.0.tgz
tar zxf rubygems-1.2.0.tgz
cd rubygems-1.2.0
ruby setup.rb

Install Gems Needed By My Site And By Rails 2.1

I have two ways to access gems I need:

  • Use the gem command to download the gems I need
  • Copy the gems from an existing ruby install
I studied which gems I would need to run this site.

I decided that I needed these gems:


-rw-r--r--  1 bikle  bikle  107520 Aug 28 23:10 actionmailer-2.1.0.gem
-rw-r--r--  1 bikle  bikle  740864 Aug 28 23:10 actionpack-2.1.0.gem
-rw-r--r--  1 bikle  bikle  452096 Aug 28 23:10 activerecord-2.1.0.gem
-rw-r--r--  1 bikle  bikle   39424 Aug 28 23:10 activeresource-2.1.0.gem
-rw-r--r--  1 bikle  bikle  358912 Aug 28 23:10 activesupport-2.1.0.gem
-rw-r--r--  1 bikle  bikle   11776 Aug 28 23:10 cgi_multipart_eof_fix-2.5.0.gem
-rw-r--r--  1 bikle  bikle   47616 Aug 28 23:10 coderay-0.7.4.215.gem
-rw-r--r--  1 bikle  bikle   31232 Aug 28 23:10 daemons-1.0.10.gem
-rw-r--r--  1 bikle  bikle   24064 Aug 28 23:10 fastthread-1.0.1.gem
-rw-r--r--  1 bikle  bikle   13312 Aug 30 09:46 fcgi-0.8.7.gem
-rw-r--r--  1 bikle  bikle   33280 Aug 28 23:10 gem_plugin-0.2.3.gem
-rw-r--r--  1 bikle  bikle  217088 Aug 28 23:10 hpricot-0.6.gem
-rw-r--r--  1 bikle  bikle   29184 Aug 28 23:10 linecache-0.43.gem
-rw-r--r--  1 bikle  bikle  105472 Aug 28 23:04 mongrel-1.1.5.gem
-rw-r--r--  1 bikle  bikle   24064 Aug 28 23:10 mongrel_cluster-1.0.5.gem
-rw-r--r--  1 bikle  bikle   33280 Aug 28 23:10 mysql-2.7.gem
-rw-r--r--  1 bikle  bikle  204288 Aug 28 23:10 rails-2.1.0.gem
-rw-r--r--  1 bikle  bikle   90112 Aug 28 23:10 rake-0.8.1.gem
-rw-r--r--  1 bikle  bikle   31744 Aug 28 23:10 ruby-debug-base-0.10.1.gem
-rw-r--r--  1 bikle  bikle   15360 Aug 28 23:10 syntax-1.0.0.gem
-rw-r--r--  1 bikle  bikle   34816 Aug 28 23:10 will_paginate-2.2.2.gem

I found the gems I needed on another host.

On that host I found them in this directory:

/usr/local/lib/ruby/gems/1.8/cache/

I copied them to ~/tmp/ of bsdbox.

I ran these shell commands:


cd ~/tmp/

gem install actionmailer             --no-ri --no-rdoc
gem install actionpack               --no-ri --no-rdoc
gem install activerecord             --no-ri --no-rdoc
gem install activeresource           --no-ri --no-rdoc
gem install activesupport            --no-ri --no-rdoc
gem install cgi_multipart_eof_fix    --no-ri --no-rdoc
gem install coderay                  --no-ri --no-rdoc
gem install daemons                  --no-ri --no-rdoc
gem install fastthread               --no-ri --no-rdoc
gem install fcgi                     --no-ri --no-rdoc
gem install gem_plugin               --no-ri --no-rdoc
gem install hpricot                  --no-ri --no-rdoc
gem install linecache                --no-ri --no-rdoc
gem install mongrel                  --no-ri --no-rdoc
gem install mongrel_cluster          --no-ri --no-rdoc
gem install mysql                    --no-ri --no-rdoc
gem install rails                    --no-ri --no-rdoc
gem install rake                     --no-ri --no-rdoc
gem install ruby-debug-base          --no-ri --no-rdoc
gem install syntax                   --no-ri --no-rdoc
gem install will_paginate            --no-ri --no-rdoc

Run The "rails" Command

I then verified that I had Rails 2.1 installed in my home directory:


[bikle@bsdbox ~/tmp]$
[bikle@bsdbox ~/tmp]$ which rails
/home/bikle/r/bin/rails
[bikle@bsdbox ~/tmp]$
[bikle@bsdbox ~/tmp]$ rails --version
Rails 2.1.0
[bikle@bsdbox ~/tmp]$
I decided to run my site from this location in the file system:

~/pt/w/b/b16/

I used the "rails" command to create it:


cd ~/pt/w/b/
rails b16

Edit config/database.yml

The database.yml helps a Rails site connect to a database.

For this site I created a MySQL database with these commands:

Shell command:

mysql -u root -p

Then, mysql command:

create database b16;

Next, I edited this file:

~/pt/w/b/b16/config/database.yml

It looks like this:


production:
  adapter: mysql
  database: b16
  username: root
  password: pass1234xyz
  host: localhost
  # useful syntax to remember but not used here:
  # socket: /bn/mysql/tmp/mysql.sock

Design/Write Layout

I searched around for pages I like.

I like this page:

http://quotedprintable.com/archives/2007/11

I copied it to this location:

~/pt/w/b/b16/app/views/layouts/application.html.erb

I worked with it until I ended up with this:


<!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>
    <title>http://bikle.com</title>
    <meta http-equiv="content-type" content="text/html; charset=UTF-8" />
    <link href="/stylesheets/layout.css" rel="stylesheet" type="text/css" />
    <link href="/stylesheets/content.css" rel="stylesheet" type="text/css" />
    <link href="/stylesheets/syntax.css" rel="stylesheet" type="text/css" />
    <link href="/stylesheets/local.css" rel="stylesheet" type="text/css" />
    <link href="/stylesheets/application.css" rel="stylesheet" type="text/css" />
    <!-- Used to highlight code -->
    <script src="/javascripts/code_highlighter.js" type="text/javascript"></script>
    <script src="/javascripts/ruby.js" type="text/javascript"></script>
    <script src="/javascripts/sql.js" type="text/javascript"></script>
    <script src="/javascripts/html.js" type="text/javascript"></script>
    <script src="/javascripts/css.js" type="text/javascript"></script>
    <script src="/javascripts/javascript.js" type="text/javascript"></script>
    <!-- Used to highlight code -->
    <!-- Used by Active Scaffold -->
    <%= javascript_include_tag :defaults %>
    <%= active_scaffold_includes %>
    <%= stylesheet_link_tag 'active_scaffold_overrides' %>
    <!-- Used by Active Scaffold -->
  </head>
  <body>
    <div id="container">
      <div id="header">
        <h1><span><a href="http://bikle.com/">http://bikle.com</a></span></h1>
        <h2>contact: bikle@bikle.com</h2>
      </div> <!-- id header -->
      <div id="page">
        <div id="content" >
          <div style="width:100%; height:90%; overflow:auto;">
            <%= yield %>
          </div>
        </div>  <!-- id content -->
        <div id="sidebar">

          <div class="sidebar-node">
            <!-- SiteSearch Google -->
            <form method="get" action="http://www.google.com/custom" target="google_window">
            <table border="0" >
            <!--
            <tr><td nowrap="nowrap" valign="top" align="left" height="32">
            <a href="http://www.google.com/">
            <img id="googlelogo" src="http://www.google.com/logos/Logo_25wht.gif" border="0" alt="Google" align="middle"></img></a>
            </td></tr>
            -->
            <tr><td nowrap="nowrap">
            <input type="hidden" name="domains" value="bikle.com"></input>

            <input type="text" name="q" size="22" maxlength="155" value="oracle"></input>
            </td></tr>

            <tr><td>
            <input type="radio" name="sitesearch" value=""  checked="checked"></input>
            <font size="-1" color="#000000">the universe</font>

            <input type="radio" name="sitesearch" value="bikle.com"></input>
            <font size="-1" color="#000000">bikle.com</font>
            <br />
            <input type="submit" name="sa" value="Google Generic Search"></input>
            <input type="hidden" name="client" value="pub-8965802770706416"></input>
            <input type="hidden" name="forid" value="1"></input>
            <input type="hidden" name="ie" value="UTF-8"></input>
            <input type="hidden" name="oe" value="UTF-8"></input>

            <input type="hidden" name="cof" value="GALT:#008000;GL:1;DIV:#336699;VLC:663399;AH:center;BGC:FFFFFF;LBGC:336699;ALC:0000FF;LC:0000FF;T:000000;GFNT:0000FF;GIMP:0000FF;FORID:1"></input>
            <input type="hidden" name="hl" value="en"></input>
            </td></tr>

            </table>
            </form>
            <hr />
            <!-- SiteSearch Google -->
          </div> <!-- class sidebar-node -->

          <div class="sidebar-node">
            <h3>Dan</h3>
            Dan Bikle is an Oracle DBA and Rails Developer.
          </div>  <!-- class sidebar-node -->
          <br />

          <div class="sidebar-node">
            <h3>Links</h3>
              <a href="/protected/about/">About</a>
              <br /><a href="/protected/services/">Services</a>
              <br /><a href="/protected/contact/">Contact</a>
              <br /><a href="/protected/tech_tips/">Tech Tips</a>
              <br /><a href="/protected/sitecode/">The Code Behind This Site</a>
              <br /><a href="/old_site.html" target="j">Old Bikle.com Site</a>
              <br />
              <br />
            <h3>Many2Many</h3>
            <a href="/asls/categs/">A Category<br />has-and-belongs-to-many<br />URLs</a>
            <p />
            <a href="/asls/urlls/">A URL<br />has-and-belongs-to-many<br />Categories</a>
          </div>  <!-- class sidebar-node -->
          <br />

          <div class="sidebar-node">
            <h3>Translate</h3>
            <a target="x" href="http://translate.google.com/translate?u=http%3A%2F%2Fbikle.com&langpair=en%7Ces&hl=en&ie=UTF-8&oe=UTF-8">Español</a>
            <br /><a target="x" href="http://translate.google.com/translate?u=http%3A%2F%2Fbikle.com&langpair=en%7Czh-CN&hl=en&ie=UTF-8&oe=UTF-8">中国版</a>
            <br /><a target="x" href="http://translate.google.com/translate?u=http%3A%2F%2Fbikle.com&langpair=en%7Cru&hl=en&ie=UTF-8&oe=UTF-8">Россия</a>
            <br /><a target="x" href="http://translate.google.com/translate?u=http%3A%2F%2Fbikle.com&langpair=en%7Cpt&hl=en&ie=UTF-8&oe=UTF-8">Português</a>
            <br /><a target="x" href="http://translate.google.com/translate?u=http%3A%2F%2Fbikle.com&langpair=en%7Cde&hl=en&ie=UTF-8&oe=UTF-8">Deutsche</a>
            <br /><a target="x" href="http://translate.google.com/translate?u=http%3A%2F%2Fbikle.com&langpair=en%7Cfr&hl=en&ie=UTF-8&oe=UTF-8">Française</a>
            <br /><a target="x" href="http://translate.google.com/translate?u=http%3A%2F%2Fbikle.com&langpair=en%7Cko&hl=en&ie=UTF-8&oe=UTF-8">한국말</a>
            <br /><a target="x" href="http://translate.google.com/translate?u=http%3A%2F%2Fbikle.com&langpair=en%7Cja&hl=en&ie=UTF-8&oe=UTF-8">日本人</a>
            <br /><a target="x" href="http://translate.google.com/translate?u=http%3A%2F%2Fbikle.com&langpair=en%7Car&hl=en&ie=UTF-8&oe=UTF-8">اللغة العربية</a>
            <br />
            <br /><a target="x" href="http://translate.google.com/translate_s?hl=en&clss=&q=oracle+database+administrator&tq=&sl=en&tl=pt">1. Translate Your Search <br />2. Translate Results Back</a>

          </div>  <!-- class sidebar-node -->

          <hr />
          <div class="sidebar-node">
            <a target="colorw" href="http://www.ficml.org/jemimap/style/color/wheel.html">
              <img src="/images/hsvwheel.png" alt="4096 color wheel" border="1" height="63" width="142" />
            </a>
          </div>  <!-- class sidebar-node -->

          <hr />
          <hr />
          <div class="sidebar-node">

<!-- google 160 wide sky scraper 2008_08_30 channel bikle.com -->
<script type="text/javascript"><!--
google_ad_client = "pub-8965802770706416";
/* 160x600 skyscraper 2008-08-30 */
google_ad_slot = "2209738515";
google_ad_width = 160;
google_ad_height = 600;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
<!-- google 160 wide sky scraper 2008_08_30 channel bikle.com -->

          </div>  <!-- class sidebar-node -->


        </div> <!-- class sidebar -->
      </div> <!-- id page -->

      <div id="footer">
        <a href="http://bikle.com/">http://bikle.com</a>
        is powered by <a href="http://api.rubyonrails.com/">Rails</a>,
        <a target='a' href='http://activescaffold.com/'>http://activescaffold.com/</a>
        and styled with <a href="http://quotedprintable.com/pages/scribbish">scribbish</a>.

        <a href="http://validator.w3.org/check?uri=referer" target="v">
          <img src="http://www.w3.org/Icons/valid-xhtml10" alt="Valid XHTML 1.0 Strict" height="15" width="44" />
        </a>

        <a href="http://jigsaw.w3.org/css-validator/" target="v2">
          <img style="border:0;width:44px;height:15px" src="http://jigsaw.w3.org/css-validator/images/vcss-blue" alt="Valid CSS!" />
        </a>

      </div> <!-- id footer -->
    </div> <!-- id container -->

<!-- google analytics -->
<script src="http://www.google-analytics.com/urchin.js" type="text/javascript">
</script>
<script type="text/javascript">
_uacct = "UA-1163628-1";
urchinTracker();
</script>
<!-- google analytics -->

  </body>
</html>

script/generate controller protected

Next I added a controller to the site. I named the controller "protected".

I did this via the Rails shell command listed below:


cd ~/pt/w/b/b16/
script/generate controller protected

This controller allows access to these links:

I used emacs to add a small amount of syntax to the controller:


class ProtectedController < ApplicationController

  caches_page :index
  caches_page :about
  caches_page :services
  caches_page :contact
  caches_page :tech_tips
  caches_page :o10gR2_solaris10x86
  caches_page :roracle_session
  caches_page :sitecode

  def index
  end

  def about
  end

  def services
  end

  def contact
  end

  def tech_tips
  end

  def  o10gR2_solaris10x86
  end

  def  roracle_session
  end

  def  sitecode
  end

end

Author Content

After I finished the controller, I authored the documents which correspond to the controller actions.

The file system view of the documents is listed below:


[bikle@bsdbox ~/pt/w/b/b16/app/views/protected]$
[bikle@bsdbox ~/pt/w/b/b16/app/views/protected]$
[bikle@bsdbox ~/pt/w/b/b16/app/views/protected]$ pwd
/home/bikle/pt/w/b/b16/app/views/protected
[bikle@bsdbox ~/pt/w/b/b16/app/views/protected]$ ls -la
total 80
drwxr-xr-x  2 bikle  bikle    512 Aug 29 23:08 .
drwxr-xr-x  7 bikle  bikle    512 Aug 25 09:27 ..
-rw-r--r--  1 bikle  bikle   4606 Aug 24 06:57 about.html.erb
-rw-r--r--  1 bikle  bikle   1725 Aug 26 22:29 contact.html.erb
-rw-r--r--  1 bikle  bikle     78 Aug 24 02:16 index.html.erb
-rw-r--r--  1 bikle  bikle  31226 Aug 30 20:04 o10gR2_solaris10x86.html.erb
-rw-r--r--  1 bikle  bikle  27606 Aug 31 14:30 roracle_session.html.erb
-rw-r--r--  1 bikle  bikle   1155 Aug 26 22:20 services.html.erb
-rw-r--r--  1 bikle  bikle    714 Aug 26 22:37 tech_tips.html.erb
[bikle@bsdbox ~/pt/w/b/b16/app/views/protected]$
[bikle@bsdbox ~/pt/w/b/b16/app/views/protected]$
[bikle@bsdbox ~/pt/w/b/b16/app/views/protected]$ cat tech_tips.html.erb
<h5>Tech Tips</h5>
<p />
<%= link_to 'Oracle 10g R2 [10.2.0.2] Install on Solaris 10 x86', :action => "o10gR2_solaris10x86" %> <br /> <p />
<p />
<%= link_to 'Copying Data From A Ruby On Rails Session Into An Oracle Session', :action => "roracle_session" %> <br /> <p />
<p />
<a href="http://www.google.com/custom?domains=bikle.com&q=burrito+recipes&sitesearch=&sa=Google+Generic+Search&client=pub-8965802770706416&forid=1&ie=UTF-8&oe=UTF-8&cof=GALT%3A%23008000%3BGL%3A1%3BDIV%3A%23336699%3BVLC%3A663399%3BAH%3Acenter%3BBGC%3AFFFFFF%3BLBGC%3A336699%3BALC%3A0000FF%3BLC%3A0000FF%3BT%3A000000%3BGFNT%3A0000FF%3BGIMP%3A0000FF%3BFORID%3A1&hl=en" target="b"><img alt="tech_tips" src="/images/tech_tips.jpg" /> </a>
[bikle@bsdbox ~/pt/w/b/b16/app/views/protected]$
[bikle@bsdbox ~/pt/w/b/b16/app/views/protected]$
[bikle@bsdbox ~/pt/w/b/b16/app/views/protected]$

Color highlighting of syntax is done with the help of JavaScript software written by Dan Webb:

http://svn.danwebb.net/external/CodeHighlighter/trunk/

The above software depends on this CSS syntax:


/*--------------------------------------------------------------
 For Dan Webb's unobtrusive code highlighter
 --------------------------------------------------------------*/

#content pre  code { color: white; }
#content code span.comment  { color: #555;     }
#content code span.string   { color: #66cc33;  }
#content code span.brackets { color: #fff;     }
#content code span.keywords { color: #cc7833;  }
#content code span.symbol   { color: #3387cc;  }
#content code span.defname  { color: #9966ff;     }
#content code span.erb      { background: #66ffff;}
#content code span.tag      { color: #ff3333;     }
#content code span.selectors  { color: #cc9900;   }
#content code span.properties { color: #006699; }
#content code span.units    { color: #ffff99;     }
#content code span.urls     { color: #3300ff;    }
#content code span.doctype  { color: #99ffff;    }
#content code span.global  { color: #ff33cc;    }

The above CSS syntax is served to you from this file:

/stylesheets/syntax.css

Which you will see listed in the head-tag of the layout.

The above syntax depends on me, the author, to make use of pre-tags, code-tags, and a class inside the code tag.

On this site I make use of the classes: html, ruby, sql, javascript, and css.

I display an example of syntax highlighting some ruby code below:

<pre><code class="ruby">
class Categ &lt; ActiveRecord::Base
  has_and_belongs_to_many :urlls
end
</code></pre>

The result:


class Categ < ActiveRecord::Base
  has_and_belongs_to_many :urlls
end

The key idea that Dan Webb worked with is that he could write JavaScript to scan HTML in every response. The JavaScript looks for elements which contain the tags "pre" and then "code". If his JavaScript finds such an element it will add span tags at appropriate places. Eventually the HTML will load in the reader's browser. The browser detects the added span tags and applies CSS from /stylesheets/syntax.css.

This site serves Dan Webb's software to you via these links which reside in the head-element of the layout:

I wrote this JavaScript to highlight SQL:

/javascripts/sql.js

sql.js is displayed below:


CodeHighlighter.addStyle("sql",{
        comment : {
                exp  : /(--[^\n]+)|(\/\*[^*]*\*+([^\/][^*]*\*+)*\/)/
        },
        brackets : {
                exp  : /\(|\)/
        },
        string : {
                exp  : /'[^']*'|"[^"]*"/
        },
        symbol : {
                exp  : /\b(SELECT|INSERT|UPDATE|DELETE|MERGE|WHERE|AND|OR|FROM|CREATE|TABLE|NUMBER|VARCHAR2|RAW|DATE|TABLESPACE|INDEX|VIEW|AS|GROUP|ORDER|BY|MAX|MIN|AVG|COUNT|ABS|UNION|COLUMN|FORMAT|SET|RULES)\b/
        }
});

Many2Many

Next, I started work on the site to expose a data-store of URLs.

A URL can belong to several categories.

The database jargon I use to describe the relationship between URLs and Categories is this:

"Many to Many"

The Rails jargon is more verbose:

"A URL has and belongs to many Categories."

"A Categroy has and belongs to many URLs."

git ActiveScaffold

I depend on a Rails-plugin named ActiveScaffold to implement this functionality.

I used a utility named "git" to get the ActiveScaffold software to my Mac.

Screen dump of git:


mac2:/software/tmp maco$
mac2:/software/tmp maco$
mac2:/software/tmp maco$ git clone git://github.com/activescaffold/active_scaffold.git
Initialize active_scaffold/.git
Initialized empty Git repository in /software/tmp/active_scaffold/.git/
remote: Counting objects: 4397, done.
remote: Compressing objects: 100% (969/969), done.
remote: Total 4397 (delta 3215), reused 4393 (delta 3211)
Receiving objects: 100% (4397/4397), 586.36 KiB | 302 KiB/s, done.
Resolving deltas: 100% (3215/3215), done.
mac2:/software/tmp maco$
mac2:/software/tmp maco$
mac2:/software/tmp maco$ ls -la active_scaffold/
total 88
drwxr-xr-x   16 maco  admin   544 Aug 30 15:31 ./
drwxr-xr-x    8 maco  admin   272 Aug 30 15:31 ../
drwxr-xr-x   12 maco  admin   408 Aug 30 15:31 .git/
-rw-r--r--    1 maco  admin  9675 Aug 30 15:31 CHANGELOG
-rw-r--r--    1 maco  admin  1057 Aug 30 15:31 MIT-LICENSE
-rw-r--r--    1 maco  admin   757 Aug 30 15:31 README
-rw-r--r--    1 maco  admin   582 Aug 30 15:31 Rakefile
-rw-r--r--    1 maco  admin  2416 Aug 30 15:31 environment.rb
drwxr-xr-x    3 maco  admin   102 Aug 30 15:31 frontends/
-rw-r--r--    1 maco  admin   476 Aug 30 15:31 init.rb
-rw-r--r--    1 maco  admin  1012 Aug 30 15:31 install.rb
-rw-r--r--    1 maco  admin  1325 Aug 30 15:31 install_assets.rb
drwxr-xr-x   18 maco  admin   612 Aug 30 15:31 lib/
drwxr-xr-x    3 maco  admin   102 Aug 30 15:31 public/
drwxr-xr-x   11 maco  admin   374 Aug 30 15:31 test/
-rw-r--r--    1 maco  admin   258 Aug 30 15:31 uninstall.rb
mac2:/software/tmp maco$
mac2:/software/tmp maco$
mac2:/software/tmp maco$

Then I copied the ActiveScaffold software to this location on the FreeBSD box:

/home/bikle/pt/w/b/b16/vendor/plugins/active_scaffold

Generate Models For ActiveScaffold

I used two shell commands to generate models for ActiveScaffold:


cd ~/pt/w/b/b16/
script/generate model categ
script/generate model urll

The file system view of the resulting models:


[bikle@bsdbox ~/pt/w/b/b16/app/models]$
[bikle@bsdbox ~/pt/w/b/b16/app/models]$ pwd
/home/bikle/pt/w/b/b16/app/models
[bikle@bsdbox ~/pt/w/b/b16/app/models]$
[bikle@bsdbox ~/pt/w/b/b16/app/models]$
[bikle@bsdbox ~/pt/w/b/b16/app/models]$ ls -la
total 8
drwxr-xr-x  2 bikle  bikle  512 Aug 25 03:09 .
drwxr-xr-x  6 bikle  bikle  512 Aug 24 02:04 ..
-rw-r--r--  1 bikle  bikle   70 Aug 25 03:09 categ.rb
-rw-r--r--  1 bikle  bikle   70 Aug 25 03:08 urll.rb
[bikle@bsdbox ~/pt/w/b/b16/app/models]$
[bikle@bsdbox ~/pt/w/b/b16/app/models]$

I used emacs to enhance the model files:


class Categ < ActiveRecord::Base
  has_and_belongs_to_many :urlls
end


class Urll < ActiveRecord::Base
  has_and_belongs_to_many :categs
end

rake db:migrate

Rails provides a utility to help me manage tables in my database.

Here is the flow:

  • Generate models (which I just did)
  • Edit corresponding "migration" files
  • Run the utility via shell command: "rake db:migrate"

So, I edited my migration files and then ran shell command: "rake db:migrate".

The migration files are listed below:


[bikle@bsdbox ~/pt/w/b/b16/db/migrate]$
[bikle@bsdbox ~/pt/w/b/b16/db/migrate]$
[bikle@bsdbox ~/pt/w/b/b16/db/migrate]$ pwd
/home/bikle/pt/w/b/b16/db/migrate
[bikle@bsdbox ~/pt/w/b/b16/db/migrate]$
[bikle@bsdbox ~/pt/w/b/b16/db/migrate]$
[bikle@bsdbox ~/pt/w/b/b16/db/migrate]$ ls -la
total 10
drwxr-xr-x  2 bikle  bikle  512 Aug 25 06: 59 .
drwxr-xr-x  3 bikle  bikle  512 Aug 30 08: 31 ..
-rw-r--r--  1 bikle  bikle  204 Aug 25 03: 10 20080825030744_create_categs.rb
-rw-r--r--  1 bikle  bikle  262 Aug 25 03: 11 20080825030802_create_urlls.rb
-rw-r--r--  1 bikle  bikle  274 Aug 25 03: 13 20080825030804_create_categs_urlls.rb
[bikle@bsdbox ~/pt/w/b/b16/db/migrate]$
[bikle@bsdbox ~/pt/w/b/b16/db/migrate]$
[bikle@bsdbox ~/pt/w/b/b16/db/migrate]$ cat 20080825030744_create_categs.rb
class CreateCategs < ActiveRecord::Migration
  def self.up
    create_table :categs do |t|
      t.column :name, :string
      t.timestamps
    end
  end

  def self.down
    drop_table :categs
  end
end
[bikle@bsdbox ~/pt/w/b/b16/db/migrate]$
[bikle@bsdbox ~/pt/w/b/b16/db/migrate]$
[bikle@bsdbox ~/pt/w/b/b16/db/migrate]$ cat 20080825030802_create_urlls.rb
class CreateUrlls < ActiveRecord::Migration
  def self.up
    create_table :urlls do |t|
      t.column :name, :string
      t.column :uurl, :string
      t.column :ddesc, :string
      t.timestamps
    end
  end

  def self.down
    drop_table :urlls
  end
end
[bikle@bsdbox ~/pt/w/b/b16/db/migrate]$
[bikle@bsdbox ~/pt/w/b/b16/db/migrate]$
[bikle@bsdbox ~/pt/w/b/b16/db/migrate]$ cat 20080825030804_create_categs_urlls.rb
class CreateCategsUrlls < ActiveRecord::Migration
  def self.up
    create_table :categs_urlls, :id => false do |t|
      t.column :categ_id, :integer
      t.column :urll_id, :integer
      t.timestamps
    end
  end

  def self.down
    drop_table :categs_urlls
  end
end
[bikle@bsdbox ~/pt/w/b/b16/db/migrate]$
[bikle@bsdbox ~/pt/w/b/b16/db/migrate]$
[bikle@bsdbox ~/pt/w/b/b16/db/migrate]$

Next, I used a series of SQL commands to fill the tables with data. You may see the data here:

Generate Controllers For ActiveScaffold

One of the main ideas behind ActiveScaffold is that each model needs its own controller.

I used these shell commands to create two controllers for my two ActiveScaffold models:


cd ~/pt/w/b/b16/
script/generate controller asls/categs
script/generate controller asls/urlls

A file system view of the controllers is displayed below:


[bikle@bsdbox ~/pt/w/b/b16/app/controllers/asls]$
[bikle@bsdbox ~/pt/w/b/b16/app/controllers/asls]$ pwd
/home/bikle/pt/w/b/b16/app/controllers/asls
[bikle@bsdbox ~/pt/w/b/b16/app/controllers/asls]$
[bikle@bsdbox ~/pt/w/b/b16/app/controllers/asls]$
[bikle@bsdbox ~/pt/w/b/b16/app/controllers/asls]$ cat categs_controller.rb
class Asls::CategsController < ApplicationController
  # active_scaffold creates powerful JS based forms.  See http://activescaffold.com
  active_scaffold do |config|
    config.label = "A Category has-and-belongs-to-many URLs"
    config.actions = [:list, :show, :search]
    config.columns[:name].label = "This Category"
    config.columns[:urlls].label = "Has These URLs"
    config.list.columns = [:name, :urlls]
    config.list.per_page = 99
    # config.list.sorting = [{ :name => :asc}]
  end
end
[bikle@bsdbox ~/pt/w/b/b16/app/controllers/asls]$
[bikle@bsdbox ~/pt/w/b/b16/app/controllers/asls]$
[bikle@bsdbox ~/pt/w/b/b16/app/controllers/asls]$ cat urlls_controller.rb
class Asls::UrllsController < ApplicationController
  # active_scaffold creates powerful JS based forms.  See http://activescaffold.com
  active_scaffold do |config|
    config.label = "A URL has-and-belongs-to-many Categories"
    config.columns[:uurl].label = "This URL"
    config.columns[:name].label = "Has This Name"
    config.columns[:ddesc].label = "And This Description"
    config.columns[:categs].label = "And These Categories"
    config.list.columns = [:uurl, :name, :ddesc, :categs]
    config.actions = [:list, :show, :search]
    config.list.per_page = 99
    # config.list.sorting = [{ :categs => :desc}, {:uurl => :desc}]
  end
end
[bikle@bsdbox ~/pt/w/b/b16/app/controllers/asls]$
[bikle@bsdbox ~/pt/w/b/b16/app/controllers/asls]$

Enhance ActiveScaffold Deployment

After I confirmed that ActiveScaffold was functional, I enhanced the display of various data values inside ActiveScaffold. I did this by editing a file named application_helper.rb A file system view of application_helper.rb is displayed below:


[bikle@bsdbox ~/pt/w/b/b16/app/helpers]$
[bikle@bsdbox ~/pt/w/b/b16/app/helpers]$ pwd
/home/bikle/pt/w/b/b16/app/helpers
[bikle@bsdbox ~/pt/w/b/b16/app/helpers]$
[bikle@bsdbox ~/pt/w/b/b16/app/helpers]$ cat application_helper.rb
# Methods added to this helper will be available to all templates in the application.
module ApplicationHelper

  # Builds a Google CSE URL from a string
  def googlethis(s)
    # Use url_for() to help prep params for the google <a> tag
    p1 = url_for( {'q' => s, 'cx' => '010334745099783175565:49dkyo8ytbk', 'cof' => 'FORID:1', :controller => "jjnnkk", :trailing_slash => false} )
    # But wait, url_for() puts tokens in there I dont want.
    # So, I use a jjnnkk controller to help me corral them.  I will then clobber them with a .sub()
    p2 = p1.sub(/^.*jjnnkk/,'')
    s3 = "<a class='googlethis' target='git' href='http://google.com/cse#{p2}'>"
    s5 = "Google-This: </a>"
    return "#{s3}#{s5}"
  end

#  # Builds a simple a-tag from a string.  String assumed to be like http://ibm.com
#  def uurl_column(record)
#    "<a target='uurl'  href='#{record.uurl}'>#{record.uurl}</a>"
#  end

  # Builds a simple a-tag from a string.  String assumed to be like http://ibm.com
  def uurl_column(record)
    s1 = "<a target='uurl'  href='#{record.uurl}'>#{record.uurl}</a>"
    return "#{googlethis(record.uurl)} #{s1}"
  end

  # Prepends a googlethis to values in name column.
  def name_column(record)
    n = record.name
    return "#{googlethis(n)} #{n}"
  end

  # Builds a ul-element from a collection of record.categs
  def categs_column(record)
    strng = ""
    record.categs.each {|e| strng << "<li /> #{link_to(h(e.name), :action => :show, :controller => 'categs', :id => e)}" }
    return "<ul> #{strng} </ul>"
  end

  # Builds a ul-element from a collection of record.names and record.urlls
  def urlls_column(record)
    # Start with empty array which I will use to ease sorting
    sa = []
    # Fill the array
    record.urlls.each {|e| sa << [e.name, e.uurl, e.id] }
    # Sort the array and use it.
    strng = ""
    sa.sort.each do |e|
#    record.urlls.each do |e|
      e_name = e[0]
      e_uurl = e[1]
      e_id   = e[2]
      strng << "<p />    <li />name: #{link_to(h(e_name), :action => :show, :controller => 'urlls', :id => e_id)}"
      strng << "<br />#{h('URL ->')}<a target='uurl' href='#{e_uurl}'>#{e_uurl}</a>"
    end
    return "<ul> #{strng} </ul>"
  end

end

[bikle@bsdbox ~/pt/w/b/b16/app/helpers]$
[bikle@bsdbox ~/pt/w/b/b16/app/helpers]$
[bikle@bsdbox ~/pt/w/b/b16/app/helpers]$

The main idea behind the above file is that ActiveScaffold allows me to overwrite some methods.

Each column in the database has a method which I can overwrite.

For example, if I have a table named cats which has a column named cat_name then, ActiveScaffold will allow me to overwrite a method called "cat_name_column()".

Example1 is displayed below:


# Methods added to this helper will be available to all templates in the application.
module ApplicationHelper
  def cat_name_column(record)
    # Every cat is now named "Rascal!"
    return "Rascal!"
  end
end

Example2 is displayed below:


# Methods added to this helper will be available to all templates in the application.
module ApplicationHelper
  def cat_name_column(record)
    # Append "Kitty" to the end of every cat name
    return record + " Kitty"
  end
end

Example3 is displayed below:


# Methods added to this helper will be available to all templates in the application.
module ApplicationHelper
  def cat_owners_column(record)
    # A cat may have several owners. So, display them in html-ul-element
    strng = ""
    record.cat_owners.each {|e| strng << "<li /> #{e.cat_owner}"}
    return "<ul> #{strng} </ul>"
  end
end

You will find more examples of enhancing ActiveScaffold deployment near the bottom of this page:

http://hpricot.com/demos

(Inside the page, search for: application_helper.rb )

ActiveScaffold is dependent on both CSS and JavaScript. I added this software by adding these lines to the head-element of the layout:


    <!-- Used by Active Scaffold -->
    <%= javascript_include_tag :defaults %>
    <%= active_scaffold_includes %>
    <%= stylesheet_link_tag 'active_scaffold_overrides' %>
    <!-- Used by Active Scaffold -->

It seems magical that ActiveScaffold JavaScript appeared in /javascripts/; I did not put it there. Perhaps it is copied to there from ~pt/w/b/b16/vendor/plugins/active_scaffold/frontends/default/javascripts/ by ActiveScaffold when Rails starts up.

Summary

Hosting

Operating System

Database

Install Ruby

Install RubyGems

Use RubyGems to install Gems I need

Run Rails command

Edit database.yml

Construct the layout

Generate the first controller

Author content

Conceptualize URL datastore as Many-to-Many

git ActiveScaffold

Generate Models For ActiveScaffold

rake db:migrate

Generate Controllers For ActiveScaffold

Enhance ActiveScaffold Deployment