TOTD #53: Scaffold in Merb using JRuby/GlassFish


GlassFish Gem 0.9.0 can be used to run Rails and Merb applications. Support another Rack-based framework Sinatra is coming up in the near future. This blog shows how to create a scaffold in Merb and run it using the GlassFish gem.



Merb allows pluggable ORM and comes with DataMapper as the default one. However DataMapper has native dependencies and so cannot be used with JRuby. There is discussion about creating a DataMapper adapter over JDBC but in the meanwhile ActiveRecord is the only ORM that can be used with JRuby.

Merb wiki has extensive documentation but lacks clearly defined steps for generating scaffold when using ActiveRecord. This blog fulfills those gaps and provides a comprehensive tutorial to build a Merb scaffold.
  1. Lets create a Merb application using ActiveRecord ORM as:

    ~/samples/jruby/merb >~/tools/jruby-1.1.5/bin/jruby -S merb-gen core --orm activerecord hello
    Generating with core generator:
         [ADDED]  gems
         [ADDED]  merb.thor
         [ADDED]  .gitignore
         [ADDED]  public/.htaccess
         [ADDED]  doc/rdoc/generators/merb_generator.rb
         [ADDED]  doc/rdoc/generators/template/merb/api_grease.js
         [ADDED]  doc/rdoc/generators/template/merb/index.html.erb
         [ADDED]  doc/rdoc/generators/template/merb/merb.css
         [ADDED]  doc/rdoc/generators/template/merb/merb.rb
         [ADDED]  doc/rdoc/generators/template/merb/merb_doc_styles.css
         [ADDED]  doc/rdoc/generators/template/merb/prototype.js
         [ADDED]  public/favicon.ico
         [ADDED]  public/merb.fcgi
         [ADDED]  public/robots.txt
         [ADDED]  public/images/merb.jpg
         [ADDED]  Rakefile
         [ADDED]  app/controllers/application.rb
         [ADDED]  app/controllers/exceptions.rb
         [ADDED]  app/helpers/global_helpers.rb
         [ADDED]  app/views/exceptions/not_acceptable.html.erb
         [ADDED]  app/views/exceptions/not_found.html.erb
         [ADDED]  autotest/discover.rb
         [ADDED]  autotest/merb.rb
         [ADDED]  autotest/merb_rspec.rb
         [ADDED]  config/init.rb
         [ADDED]  config/rack.rb
         [ADDED]  config/router.rb
         [ADDED]  config/environments/development.rb
         [ADDED]  config/environments/production.rb
         [ADDED]  config/environments/rake.rb
         [ADDED]  config/environments/staging.rb
         [ADDED]  config/environments/test.rb
         [ADDED]  public/javascripts/application.js
         [ADDED]  public/stylesheets/master.css
         [ADDED]  spec
         [ADDED]  app/views/layout/application.html.erb
  2. Generate a Merb resource (model, controller and associated things):

    ~/samples/jruby/merb/hello >merb-gen resource Runner distance:float,minutes:integer
    Loading init file from /Users/arungupta/samples/jruby/merb/hello/config/init.rb
    Loading /Users/arungupta/samples/jruby/merb/hello/config/environments/development.rb
    Generating with resource generator:
    Loading init file from /Users/arungupta/samples/jruby/merb/hello/config/init.rb
    Loading /Users/arungupta/samples/jruby/merb/hello/config/environments/development.rb
    Loading init file from /Users/arungupta/samples/jruby/merb/hello/config/init.rb
    Loading /Users/arungupta/samples/jruby/merb/hello/config/environments/development.rb
    Loading init file from /Users/arungupta/samples/jruby/merb/hello/config/init.rb
    Loading /Users/arungupta/samples/jruby/merb/hello/config/environments/development.rb
    Loading init file from /Users/arungupta/samples/jruby/merb/hello/config/init.rb
    Loading /Users/arungupta/samples/jruby/merb/hello/config/environments/development.rb
         [ADDED]  spec/models/runner_spec.rb
         [ADDED]  app/models/runner.rb
         [ADDED]  schema/migrations/001_runner_migration.rb
         [ADDED]  spec/requests/runners_spec.rb
         [ADDED]  app/controllers/runners.rb
         [ADDED]  app/views/runners/index.html.erb
         [ADDED]  app/views/runners/show.html.erb
         [ADDED]  app/views/runners/edit.html.erb
         [ADDED]  app/views/runners/new.html.erb
         [ADDED]  app/helpers/runners_helper.rb
    resources :runners route added to config/router.rb

    As evident from the generated files Model, Controller, Helper and Views are generated. The Views are only template files with no code because this code end up getting changed anyway most of the times. Instead template Views can be written as explained in CRUD View Examples (more on this later).
  3. Configure Database
    1. Merb applications do not have a pre-generated "database.yml" so create one as:

      ~/samples/jruby/merb/hello >rake db:create
      (in /Users/arungupta/samples/jruby/merb/hello)
      JRuby limited openssl loaded. gem install jruby-openssl for full support.
      http://wiki.jruby.org/wiki/JRuby_Builtin_OpenSSL
      Loading init file from /Users/arungupta/samples/jruby/merb/hello/config/init.rb
      Loading /Users/arungupta/samples/jruby/merb/hello/config/environments/development.rb
      Loading init file from /Users/arungupta/samples/jruby/merb/hello/config/init.rb
      Loading /Users/arungupta/samples/jruby/merb/hello/config/environments/development.rb
       ~ It took: 0
       ~ Loading: Merb::BootLoader::MixinSession
       ~ It took: 0
       ~ Loading: Merb::BootLoader::BeforeAppLoads
       ~ It took: 0
       ~ Loading: Merb::Orms::ActiveRecord::Connect
       ~ No database.yml file found in /Users/arungupta/samples/jruby/merb/hello/config.
       ~ A sample file was created called database.yml.sample for you to copy and edit.
    2. Copy "config/database.yml.sample" to "config/database.yml". Wonder why this step is explicitly required ?
    3. Edit database configuration such that it looks like:

      :development: &defaults
        :adapter: mysql
        :database: hello_development
        :username: root
        :password:
        :host: localhost
        :socket: /tmp/mysql.sock
        :encoding: utf8

      The changed lines are shown in bold.
    4. Create the database as:

      ~/samples/jruby/merb/hello >rake db:create
      (in /Users/arungupta/samples/jruby/merb/hello)
      JRuby limited openssl loaded. gem install jruby-openssl for full support.
      http://wiki.jruby.org/wiki/JRuby_Builtin_OpenSSL
      Loading init file from /Users/arungupta/samples/jruby/merb/hello/config/init.rb
      Loading /Users/arungupta/samples/jruby/merb/hello/config/environments/development.rb
      Loading init file from /Users/arungupta/samples/jruby/merb/hello/config/init.rb
      Loading /Users/arungupta/samples/jruby/merb/hello/config/environments/development.rb
       ~ It took: 0
       ~ Loading: Merb::BootLoader::MixinSession
       ~ It took: 0
       ~ Loading: Merb::BootLoader::BeforeAppLoads
       ~ It took: 0
       ~ Loading: Merb::Orms::ActiveRecord::Connect
       ~ Connecting to database...
       ~ It took: 0
       ~ Loading: Merb::BootLoader::LoadClasses
       ~ It took: 0
       ~ Loading: Merb::BootLoader::Router
       ~ Compiling routes...
       ~ It took: 0
       ~ Loading: Merb::BootLoader::Templates
       ~ It took: 0
       ~ Loading: Merb::BootLoader::MimeTypes
       ~ It took: 0
       ~ Loading: Merb::BootLoader::Cookies
       ~ It took: 0
       ~ Loading: Merb::BootLoader::SetupSession
       ~ It took: 1
       ~ Loading: Merb::BootLoader::SetupStubClasses
       ~ It took: 0
       ~ Loading: Merb::BootLoader::AfterAppLoads
       ~ It took: 0
       ~ Loading: Merb::BootLoader::ChooseAdapter
       ~ It took: 0
       ~ Loading: Merb::BootLoader::RackUpApplication
       ~ It took: 0
       ~ Loading: Merb::BootLoader::ReloadClasses
       ~ It took: 0
      DEPRECATION WARNING: You're using the Ruby-based MySQL library that ships with Rails. This library will be REMOVED FROM RAILS 2.2. Please switch to the offical mysql gem: `gem install mysql`  See http://www.rubyonrails.org/deprecation for details. (called from mysql_connection at /Users/arungupta/tools/jruby-1.1.5/lib/ruby/gems/1.8/gems/activerecord-2.1.2/lib/active_record/connection_adapters/mysql_adapter.rb:81)
       ~   SQL (0.000581)   SET NAMES 'utf8'
       ~   SQL (0.000581)   SET SQL_AUTO_IS_NULL=0
       ~   SQL (0.000894)   CREATE DATABASE `hello_development` DEFAULT CHARACTER SET `utf8` COLLATE `utf8_general_ci`
      MySQL hello_development database successfully created
    5. Migrate the database as:

      ~/samples/jruby/merb/hello >rake db:migrate
      (in /Users/arungupta/samples/jruby/merb/hello)
      JRuby limited openssl loaded. gem install jruby-openssl for full support.
      http://wiki.jruby.org/wiki/JRuby_Builtin_OpenSSL
      Loading init file from /Users/arungupta/samples/jruby/merb/hello/config/init.rb
      Loading /Users/arungupta/samples/jruby/merb/hello/config/environments/development.rb
      Loading init file from /Users/arungupta/samples/jruby/merb/hello/config/init.rb
      Loading /Users/arungupta/samples/jruby/merb/hello/config/environments/development.rb
       ~ It took: 0
       ~ Loading: Merb::BootLoader::MixinSession
       ~ It took: 0
       ~ Loading: Merb::BootLoader::BeforeAppLoads
       ~ It took: 0
       ~ Loading: Merb::Orms::ActiveRecord::Connect
       ~ Connecting to database...
       ~ It took: 0
       ~ Loading: Merb::BootLoader::LoadClasses
       ~ It took: 1
       ~ Loading: Merb::BootLoader::Router
       ~ Compiling routes...
       ~ It took: 0
       ~ Loading: Merb::BootLoader::Templates
       ~ It took: 0
       ~ Loading: Merb::BootLoader::MimeTypes
       ~ It took: 0
       ~ Loading: Merb::BootLoader::Cookies
       ~ It took: 0
       ~ Loading: Merb::BootLoader::SetupSession
       ~ It took: 0
       ~ Loading: Merb::BootLoader::SetupStubClasses
       ~ It took: 0
       ~ Loading: Merb::BootLoader::AfterAppLoads
       ~ It took: 0
       ~ Loading: Merb::BootLoader::ChooseAdapter
       ~ It took: 0
       ~ Loading: Merb::BootLoader::RackUpApplication
       ~ It took: 0
       ~ Loading: Merb::BootLoader::ReloadClasses
       ~ It took: 0
      DEPRECATION WARNING: You're using the Ruby-based MySQL library that ships with Rails. This library will be REMOVED FROM RAILS 2.2. Please switch to the offical mysql gem: `gem install mysql`  See http://www.rubyonrails.org/deprecation for details. (called from mysql_connection at /Users/arungupta/tools/jruby-1.1.5/lib/ruby/gems/1.8/gems/activerecord-2.1.2/lib/active_record/connection_adapters/mysql_adapter.rb:81)
       ~   SQL (0.000769)   SET NAMES 'utf8'
       ~   SQL (0.000610)   SET SQL_AUTO_IS_NULL=0
       ~   SQL (0.001609)   SHOW TABLES
       ~   SQL (0.003952)   CREATE TABLE `schema_migrations` (`version` varchar(255) NOT NULL) ENGINE=InnoDB
       ~   SQL (0.054355)   CREATE UNIQUE INDEX `unique_schema_migrations` ON `schema_migrations` (`version`)
       ~   SQL (0.001691)   SHOW TABLES
       ~   SQL (0.001643)   SELECT version FROM schema_migrations
       ~ Migrating to RunnerMigration (1)
      == 1 RunnerMigration: migrating ===============================================
      -- create_table(:runners)
       ~   SQL (0.005301)   CREATE TABLE `runners` (`id` int(11) DEFAULT NULL auto_increment PRIMARY KEY, `distance` float, `minutes` int(11), `created_at` datetime, `updated_at` datetime) ENGINE=InnoDB
         -> 0.0107s
      == 1 RunnerMigration: migrated (0.0114s) ======================================

       ~   SQL (0.014063)   INSERT INTO schema_migrations (version) VALUES ('1')
       ~   SQL (0.003585)   SHOW TABLES
       ~   SQL (0.001324)   SELECT version FROM schema_migrations
       ~   SQL (0.001451)   SHOW TABLES
       ~   SQL (0.017054)   SHOW FIELDS FROM `runners`
       ~   SQL (0.018503)   describe `runners`
       ~   SQL (0.009372)   SHOW KEYS FROM `runners`
  4. Create the CRUD views
    1. Add dependencies
      1. Edit "config/init.rb" and add the following line:

        require 'config/dependencies.rb'

        as the first uncommented line.
      2. Create "config/dependencies.rb" and add the following dependency (explained here):

        dependency "merb-assets", "1.0"
        dependency "merb-helpers", "1.0"
    2. Add the resource routes by editing "config/router.rb" and adding:

      resources :runners

      insider "Merb::Router.prepare do" block.
    3. Edit the "index" view in "app/views/runners/index.html.erb" as:

      <h1>Runner controller, index action</h1>

      <table>
        <tr>
          <th>Distance (in miles)</th>
          <th>Time (in mins)</th>

          <th colspan="3">Actions</th>
        </tr>

      <% @runners.each do |runner| %>
        <tr>
          <td><%=h runner.distance %></td>
          <td><%=h runner.minutes %></td>

          <td><%= link_to 'Show', resource(runner) %></td>
          <td><%= link_to 'Edit', resource(runner, :edit) %></td>
          <td><%= delete_button(runner, "Delete #{runner.distance}") %></td>
        </tr>
      <% end %>
      </table>

      <%= link_to 'New', resource(:runners, :new) %>
    4. Edit the "new" in "app/views/runners/new.html.erb" view as:

      <h1>Runners controller, new action</h1>

      <%= form_for(@runner, :action => resource(:runners) ) do %>
       
        <p>
          <%= text_field :distance, :label => "Distance (in miles)" %>
        </p>
       
        <p>
          <%= text_field :minutes, :label => "Time (in mins)"  %>
        </p>
       
        <p>
          <%= submit "Create" %>
        </p>
      <% end =%>
       
      <%= link_to 'Back', resource(:runners) %>
    5. Edit the "show" view in "app/views/runners/show.html.erb" as:

      <h1>Runners controller, show action</h1>

      <p>Distance (in miles): <%=h @runner.distance %></p>
      <p>Time (in mins): <%=h @runner.minutes %></p>
       
      <%= link_to 'Back', resource(:runners) %>
    6. Edit the "edit" in "app/views/runners/edit.html.erb" view as:

      <h1>Runners controller, edit action</h1>

      <%= form_for(@runner, :action => resource(@runner)) do %>
       
        <p>
          <%= text_field :distance, :label => "Distance (in miles)"  %>
        </p>
       
        <p>
          <%= text_field :minutes, :label => "Time (in mins)"  %>
        </p>
       
        <p>
          <%= submit "Update" %>
        </p>
      <% end =%>
       
      <%= link_to 'Show', resource(@runner) %> | <%= link_to 'Back', resource(:runners) %>
That's it!

And now here are some of the captured outputs.

The default output at "http://localhost:3000/runners"



Creating a new Runner at "http://localhost:3000/runners/new" as:



"Show" view of a runner at "http://localhost:3000/runners/<id>" as :



"Index" view with one runner at "http://localhost:3000/runners" as:



And now "index" view with 2 runners at "http://localhost:3000/runners" as:



A Merb app generated using MRI can also be run using GlassFish, provided it does not have any native dependencies.

And another useful piece of information is difference between Rails and Merb provide comparative syntax between Rails and Merb.

And thanks to all the discussion on merb@googlegroups where all my questions were answered very promptly!

Submit your bugs here, talk to us using GlassFish Forum, and get the latest information on JRuby wiki.

Technorati: totd glassfish v3 gem jruby rubyonrails merb
Comments:

[Trackback] GlassFish v3 with Merb and Warbler explains how to use Warbler to deploy a Merb application on GlassFish v3. Here is a quote&nbsp;from the blog: this lovely server had a gem which you can use to fire up a...

Posted by Arun Gupta's Blog on December 03, 2008 at 01:15 AM PST #

[Trackback] Supper Happy Dev House is "a premier monthly hackathon event that combines serious and not-so-serious productivity with a fun and exciting party atmosphere." The 30th monthly event was hosted at Sun Microsystem's Executive Briefing Center (aka EBC) in...

Posted by Arun Gupta's Blog on February 02, 2009 at 09:39 PM PST #

thank u arun. Thanks for information

Posted by sinema izle on March 13, 2009 at 06:31 AM PDT #

[Trackback] Sinatra is a DSL for quickly creating web-applications in Ruby with minimal effort. Like Rails and Merb, Sinatra is not an MVC framework and basically follows a flat-file structure instead. The framework define conventions such as location of static...

Posted by Arun Gupta's Blog on April 27, 2009 at 11:16 PM PDT #

[Trackback] This is a follow up post from David's keynote. Attended Women in Rails panel discussion. The panel, Sarah Mei, Lori Olson, and Desi McAdam (from L to R), had a very interesting discussion around the genuine problems and possible solutions...

Posted by Arun Gupta's Blog on May 05, 2009 at 10:40 PM PDT #

Post a Comment:
Comments are closed for this entry.
About

profile image
Arun Gupta is a technology enthusiast, a passionate runner, author, and a community guy who works for Oracle Corp.


Java EE 7 Samples

Stay Connected

Search

Archives
« April 2014
SunMonTueWedThuFriSat
  
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
   
       
Today