Skip to main content

TOTD #80: Sinatra CRUD application using Haml templates with JRuby and GlassFish Gem

Posted by arungupta on April 29, 2009 at 6:21 AM PDT



href="http://blog.arungupta.me/2009/04/27/totd-79-getting-started-with-sinatra-applications-on-jruby-and-glassfish-gem.aspx">TOTD
#79 showed how to run a trivial href="http://www.sinatrarb.com/">Sinatra
application using href="http://rubyforge.org/projects/glassfishgem/">GlassFish
Gem. Sinatra
provides support for Haml,
Erb,
Builder,
Sass,
and Inline templates as href="http://www.sinatrarb.com/intro.html">described here.
This TOTD will show how to get started with creating a Sinatra CRUD
application using Haml templates.


cellspacing="2">
style="width: 208px; height: 220px;" alt=""
src="http://blogs.sun.com/arungupta/resource/ror/haml-logo.png">
Haml is based on one primary principle - style="font-style: italic;">Markup should be beautiful
because beauty makes
you faster
.



Get started by installing the Haml gem as:


style="text-align: left; background-color: rgb(204, 204, 255); width: 100%;"
cellpadding="2" cellspacing="2">
/tools/jruby-1.2.0 > style="font-weight: bold;">./bin/jruby
-S gem install haml --no-ri --no-rdoc

JRuby limited openssl loaded. gem install jruby-openssl for full
support.

http://wiki.jruby.org/wiki/JRuby_Builtin_OpenSSL

Successfully installed haml-2.0.9

1 gem installed



And follow the tutorial,
documentation,
and href="http://haml.hamptoncatlin.com/docs/rdoc/classes/Haml.html">reference
page for more details.



Sinatra is ORM-agnostic and so any Ruby ORM framework such as href="http://api.rubyonrails.org/classes/ActiveRecord/Base.html">ActiveRecord,
DataMapper,
Sequel,
and others. DataMapper with JRuby href="http://www.datamapper.org/doku.php?id=jruby:contribute">requires
work so this TOTD will show how to use ActiveRecord instead.
There is href="http://github.com/nakajima/sinatras-hat/tree/master">sinatras-hat
which allows to create RESTy CRUD apps with Sinatra. There probably are
mutiple other ways to create this application but I prefer to
understanding the wiring so this blog will use a bare minimal structure.



Anyway, lets get started!

  1. Create the database as:


    style="text-align: left; background-color: rgb(204, 204, 255); width: 100%;"
    cellpadding="2" cellspacing="2">
    ~/tools/jruby/samples/sinatra-sample > style="font-weight: bold;">mysql --user root

    Welcome to the MySQL monitor.  Commands end with ; or \g.

    Your MySQL connection id is 664

    Server version: 5.1.30 MySQL Community Server (GPL)



    Type 'help;' or '\h' for help. Type '\c' to clear the buffer.



    mysql> create
    database hello_development;


    Query OK, 1 row affected (0.00 sec)



    mysql> use
    hello_development;


    Database changed

    mysql> CREATE
    TABLE `runners` (`id` int(11) DEFAULT NULL auto_increment PRIMARY KEY,
    `distance` float, `minutes` int(11), `created_at` datetime,
    `updated_at` datetime); 
              
     

    Query OK, 0 rows affected (0.06 sec)


  2. Update "hello.rb" from href="http://blog.arungupta.me/2009/04/27/totd-79-getting-started-with-sinatra-applications-on-jruby-and-glassfish-gem.aspx">TOTD
    #79 such that it looks like:


    style="text-align: left; background-color: rgb(204, 204, 255); width: 100%;"
    cellpadding="2" cellspacing="2">
    require 'rubygems'

    require 'sinatra'

    require 'activerecord'



    ## Setup



    ActiveRecord::Base.establish_connection(

      :adapter  => "jdbcmysql",

      :host     =>
    "localhost",

      :username => "root",

      :password => "",

      :database => "hello_development"

    )



    ## Models



    class Runner < ActiveRecord::Base

    end



    ## Controller Actions



    get '/hi' do

      "Hello World!"

    end



    get '/' do

      @runner = Runner.find(:all)

      haml :index

    end



    get '/new' do

      haml :new

    end



    get '/:id' do

      @runner = Runner.find(params[:id])

      if (@runner)

        haml :show

      else

        redirect '/'

      end

    end



    post '/' do

      @runner = Runner.new(:distance => params[:distance],
    :minutes => params[:minutes])

      if @runner.save

        redirect "/#{@runner.id}"

      else

        redirect '/'

      end

    end



    Firstly, it pulls in the ActiveRecord dependency. Then
    "ActiveRecord::Base.establish_connection" is used to establish a
    connection with the previously created database. "Runner" is tagged as
    a model class by inheriting from "ActiveRecord::Base" and uses the
    default table name ("runners" in this case). Add four new methods:

    1. Three GET methods to show all the runners, a form to
      enter new data, and show a particular log entry. Each method requires a
      HAML template (will be created in next step) to render the information.
    2. One POST method to save the newly created log entry in
      the database.
  3. Create a new directory "views" and create the following
    files in that directory. Each file serves as a view and rendered from
    an action in "hello.rb".
    1. "index.haml": Show all the runners


      style="text-align: left; background-color: rgb(204, 204, 255); width: 100%;"
      cellpadding="2" cellspacing="2">
      %h1 Listing all runners ...

      %table

        %tr

          %th Distance

          %th Minutes

        - @runner.each do |r|

          %tr

            %td= r.distance

            %td= r.minutes

      %br

      %a{:href=>"/new"}

        New Runner


    2. "new.haml": Enter a new entry


      style="text-align: left; background-color: rgb(204, 204, 255); width: 100%;"
      cellpadding="2" cellspacing="2">
      %h1 Adding a new runner log ...

      %form{:method=>"post", :action=>"/"}

        Distance:

        %input{:type=>"text", :name=>"distance"}

        %br

        Minutes:

        %input{:type=>"text", :name=>"minutes"}

        %br

        %input{:type=>"submit", :value=>"Submit"}

        %br


    3. "show.haml": Show a particular log entry


      style="text-align: left; background-color: rgb(204, 204, 255); width: 100%;"
      cellpadding="2" cellspacing="2">
      %h1 Showing a runner log ...

      Distance:

      = @runner.distance

      %br

      Minutes:

      = @runner.minutes

      %br

      %br

      %a{:href=>"/"}= "Show All!"



      The complete directory structure looks like:


      style="text-align: left; background-color: rgb(204, 204, 255); width: 100%;"
      cellpadding="2" cellspacing="2">
      .

      ./hello.rb

      ./views

      ./views/index.haml

      ./views/new.haml

      ./views/show.haml

That's it, now run the application as:


style="text-align: left; background-color: rgb(204, 204, 255); width: 100%;"
cellpadding="2" cellspacing="2">
~/tools/jruby/samples/sinatra-sample > style="font-weight: bold;">../../bin/jruby -S glassfish

Starting GlassFish server at: 192.168.1.145:3000 in development
environment...

Writing log messages to:
/Users/arungupta/tools/jruby-1.2.0/samples/sinatra-sample/log/development.log.

Press Ctrl+C to stop.



The main page is available at "http://localhost:3000/" and looks like:



alt=""
src="http://blogs.sun.com/arungupta/resource/ror/sinatra-crud-list-all-blank.png">



Clicking on "New Runner" gives ...



alt=""
src="http://blogs.sun.com/arungupta/resource/ror/sinatra-crud-add-new.png">



Enter the data, and click on "Submit" to show ...



alt=""
src="http://blogs.sun.com/arungupta/resource/ror/sinatra-crud-show-new.png">



Click on "Show All!" to see all the entries added so far ...



alt=""
src="http://blogs.sun.com/arungupta/resource/ror/sinatra-crud-list-1.png">



And after adding few entries the main page looks like ...



alt=""
src="http://blogs.sun.com/arungupta/resource/ror/sinatra-crud-list-all.png">



This application shows Create and Read from the CRUD, it's fairly easy
to add Update and Delete functionality as well but that's an excercise
left for the readers :-)



You'll hear all about it at href="http://en.oreilly.com/rails2009/public/schedule/detail/7720">Develop
with Pleasure, Deploy with Fun: GlassFish and NetBeans for a Better
Rails Experience at href="http://en.oreilly.com/rails2009/">Rails Conf
next week.



Technorati: totd
glassfish
jruby
sinatra
crud

Related Topics >>