In this tutorial you will create and configure the initial parts of a Ruby on Rails application, using the Bridge SDK and gem. If you've built Rails applications before, this will primarily be a review, but will show you how to use the SDK and gem. There is minimal introduction to Rails concepts, so please note the Assumptions/Requirements section before getting started. In this tutorial, you will:
- Create a new Rails application
- Configure the application to include the SDK and other libraries
- Create launch scripts
- Create initial assets, a controller, routes, a layout, and a view
- Access to the SDK and a functional development environment
- Familiarity with HTML and CSS and Twitter Bootstrap (Bootstrap will be used, but it is not a required to understand all the details and functionality)
- Familiarity with Ruby Gems
- Comfortable with the basics of using a command-line interface in your development environment
New rails app (not recommended)¶
Warning - If you want to make a rails app from scratch then you should be very familiar with jruby, bundler, rails, and warbler. There are a number of "gotchas" that can appear due to versions changing across multiple libraries/frameworks. Because of this we highly recommend using the vanilla rails application we provide if you want to build a new application, or downloading the code for this tutorial if you wish to follow along. Then you can skip down to First controller, layout, view, and route.
If you intend to set things up on your own, begin by creating a new Rails application. Open a console in your development environment and change directory to the location you will build your application. Run this command, substituting
RailsDeveloperTutorial for your application name (in camel case):
rails new RailsDeveloperTutorial
Now that you have a new application, the next step will be to edit the
Gemfile is how your application libraries are managed. This is done with a gem called
bundler. Additional details about the structure and management of a Rails application are available in the Rails getting started tutorial. You will remove some unnecessary gems for this project and add others. Your
Gemfile should now look like this (change the
harbinger-rails-extensions version to match what is current):
source 'https://rubygems.org' gem 'rails', '4.2.0' gem 'jquery-rails' gem 'autoprefixer-rails','6.0.3' gem 'mime-types', '~> 2.0' # Assets gem 'sass-rails', '~> 5.0' gem 'font-awesome-sass' gem 'bootstrap-sass' gem 'uglifier', '>= 1.3.0' gem 'therubyrhino' gem 'harbinger-rails-extensions', source: 'http://gem.analytical.info:9292' group :development, :test do end # Windows does not include zoneinfo files, so bundle the tzinfo-data gem gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby]
Now that you have configured the libraries needed, run this command to install them in the application development environment:
Create a directory in the root of your Rails application called
sdk and move the SDK JAR file there. You will include it in your application by editing
config/application.rb. This is where you configure an application across all Rails environments. Whenever your application runs, this is the file that defines the initial configuration. We only want to include the SDK in an application while developing, as a production deployment will source the SDK from the shared application server libraries. Add the following lines to
config/application.rb to implement this configuration (change the SDK filename to remove the version so you don't need to update your app for development whenever the SDK version changes):
# Load the SDK when in development mode # The SDK is a shared library when in production if ENV['DEV_MODE'] == "on" then require File.join(File.dirname(__FILE__),'..','sdk','harbinger-sdk-standalone.jar') end
The environment variable
DEV_MODE will be used to only load the SDK from when explicitly requested.
Bridge platform data should only be access through the SDK, but Rails wants to connect to a database by default. This behavior can be reconfigured by editing the section
require rails/all in the
config/application.rb to this:
# require 'rails/all' require 'action_controller/railtie' require 'action_mailer/railtie' require 'active_model/railtie' require 'sprockets/railtie'
You will also need to remove all references to Active Record in the configuration of this application. In Rails version
4.2.0 this requires two changes:
config/application.rbto comment out the line
config.active_record.raise_in_transactional_callbacks = trueby putting a
#in front of it.
config/environments/development.rband comment the line
config.active_record.migration_error = :page_load.
Finally, create two launch scripts in the root of your Rails application directory, one for
rails server and one for
DEV_MODE="on" JRUBY_OPTS="-J-XX:MaxPermSize=256m" rails console
DEV_MODE="on" JRUBY_OPTS="-J-XX:MaxPermSize=256m" rails server -p 3001 -b 0.0.0.0
Set each script to be executable:
chmod +x launch_dev_console chmod +x launch_dev_server
Each script sets the environment variable
DEV_MODE to "on" to ensure the SDK is loaded. This also sets the Java Virtual Machine (JVM) option to increase the Permanent Generation memory cap size to 256 megabytes. Finally, the scripts launch the rails console and server, respectively.
Additional Environment Variables¶
The Bridge server and development server will be different in many development scenarios. If this is the case, the user will likely want to point to the Bridge server for SSO. This can be accomplished by setting the SSO environment variable.
DEV_MODE="on" JRUBY_OPTS="-J-XX:MaxPermSize=256m -J-Dharbinger.sso.url=http://server.example.com:8088/openam" rails server -p 3001 -b 0.0.0.0
Tip/Best Practice - If you are connecting to the rails server from a remote host you'll need to add a
-boption to the
launch_dev_serverscript in order to allow remote connections. You can open your server to the world with
-b 0.0.0.0. However, we do not recommend doing this unless you have authentication/authorization and HIPAA auditing in place. It's much better to secure the application to the IP address/range of those doing development and testing.
You can now test that you have a working Rails application ready for Bridge development by launching the console with
./launch_dev_console and running
Java::HarbingerSdk::DataUtils.getEntityManager. Don't worry if it takes a little while for things to start up and the first entity manager to return: this is normal and will be discussed in detail in tutorial part 8.
Troubleshooting - If any of these steps are not working, confirm sure you've followed the steps in Part 2. If you still have problems, please email us or contact us via our Slack channel with details about the issue and any error message(s) you see. Please remember to filter out any PHI when sharing.
First controller, layout, view, and route¶
Note - The remainder of this tutorial will focus on building the worklist application, however if you are an experienced developer, you have completed all the required setup for Bridge-specific development. We highly recommended, however, that you complete the tutorial to learn about HIPAA audit logging and other major platform functions and features.
This will be the "Hello World" section. If you've built a Rails app before you can skim this section, but it will be helpful if you are new to Rails or the MVC pattern.
Rails implements a programming pattern known as MVC (Model View Controller). Numerous MVC frameworks have been built for web development since the pattern fits the web well. In addition to the model, view, and controller, Rails uses layouts and helpers.
- Model - Models are typically where you interact with data and define data handling objects.
- Controller - Controllers contain the logic to handle HTTP requests. Controllers also render views and often call out to Models for heavy lifting/logic.
- View - A view is what will be displayed. This is typically HTML (often built by a templating library like erb), or in the case of an API, a machine-consumable data format. Views could also be used to build Excel or CSV files.
- Layout - Layouts can be thought of as a "super" View. They typically contain the markup that wraps a page, e.g. the HTML, HEAD, and BODY tags.
- Helper - Helpers are a set of functions used by Views. Large amounts of Ruby logic inside a view can get very cluttered or duplicated (e.g. a date/time formatting function used throughout the application), so Helpers are a way to share and reuse that code.
Layout and Asset Basics¶
Setup the application layout by editing
app/views/layout/application.html.erb. This is the default layout for all views. It is also possible to create controller- or view-specific layouts (learn more about those here). Replace the default layout that Rails generated:
This file has an erb (Embedded RuBy) extension. ERB is part of the standard library for Ruby and Rails knows how to handle this file extension. Anything encapsulated in
<% %> tags is Ruby. The lines to take note of:
<%= yield %>- This is where Rails will put the views rendered by the controller before sending on the full HTTP response.
<%= stylesheet_link_tag "application", :media => "all" %>- This is turned into a CSS link tag that will include all the stylesheets referenced in
app/assets. This tutorial will not discuss all the details of the Rails asset pipeline, but a brief explanation and recommended usage follows. For more information on the asset pipeline please refer to this guide.
To simplify building an application with a consistent look and feel, use Bootstrap. Recall adding
bootstrap-sass to the
Gemfile earlier: take advantage of that gem by editing the application stylesheet. Bootstrap uses sass, a higher level CSS language. Rename
app/assets/stylesheets/application.scss, then edit:
/* *= require_self */ @import "bootstrap-sprockets"; @import "bootstrap"; @import "font-awesome-sprockets"; @import "font-awesome";
//= require jquery //= require jquery_ujs //= require bootstrap-sprockets
require_tree. Avoid using
require_tree: it can create challenging problems and silent conflicts, especially when multiple gems that provide assets are installed.
Controller and view¶
Build the first controller by creating the file
app/controllers/worklist_controller.rb. Rails expects controllers to be in the
app/controllers directory. Edit the file:
class WorklistController < ApplicationController def index @name = "Bill" end end
Controller objects handle client (HTTP) requests. Rails implements these objects as classes that inherit from an auto-generated class
ApplicationController in turn inherits from
ActionController::Base. Each time a request is made to a controller, the object is instantiated and one of its instance methods is called (Setting up a route below). By default, each instance tries to render a view of the same name inside of the
app/views/[controller_name] directory. In the case of the
index method above, Rails will try to render
app/views/worklist/index.html.erb. This can be overridden by calling render explicitly. Additionally, all instance variables set by the controller (variables prefixed with
@) are accessible to the view. In the
index method, or
action in Rails terminology, you created an instance variable
@name and set it to the string
Best Practice - Instance variables are shared across all methods within the controller and automatically shared through all views being rendered by the called method/action. That means they persist throughout the life of a request and act as a pseudo-global variable within the request lifetime. Be cautious of prefixing
@to a variable name without a good reason.
Next, create the view associated (by default) with the
index action in the
WorklistController. Make the directory
app/views/worklist then create the file
<div class="container-fluid"> <div class="row"> <div class="col-xs-12"> <h1>Future Worklist</h1> <p>My name is <%= @name %></p> </div> </div> </div>
div tags are related to Bootstraps grid system and are purely stylistic. This creates a page that will display a heading of "Future Worklist" and then "My name is [contents of
@name instance variable]".
Setting up a route¶
Routes are the way a Rails application knows how to direct a request. Routes are defined by rules in
config/routes.rb. The default routes file has some small documentation about routes, but here is a link to the routes guide. That link is to the type of routes used in this example application: Non-resource routes. Resource routes won't be used in this application tutorial.
Rails.application.routes.draw do get 'worklist' => "worklist#index" root :to => "worklist#index" end
This creates two routing rules. The first is establishes that
GET requests to
/worklist will be directed to the
index method. The second defines that requests to the root of the application
/ will also be directed there.
Best Practice - A popular (default in previous Rails verions) configuration was to provide a default route that followed the pattern of
/controller/action. While this can save time during development, we recommend that wildcard routes are removed before putting an application into production. Although arguments can be made about the best practice, our recommendation is that apps respond with a
404(Not Found) instead of a
500(Internal Server Error) when someone navigates to a page that does not exist, so this practice supports the best customer experience.
The application is ready to be run, start it using the
launch_dev_server script (created earlier):
The server will start and you should see something like this in your terminal:
=> Booting WEBrick => Rails 4.2.0 application starting in development on http://localhost:3000 => Run `rails server -h` for more startup options => Ctrl-C to shutdown server [2015-09-22 14:28:47] INFO WEBrick 1.3.1 [2015-09-22 14:28:47] INFO ruby 1.9.3 (2014-09-25) [java] [2015-09-22 14:28:47] INFO WEBrick::HTTPServer#start: pid=10289 port=3000
Tip - For this tutorial, you are using the built-in Rails development server, WEBrick. WEBrick, while functional isn't the fastest or best server. Experienced developers may want to use a different server, e.g. puma, but this is outside the scope of this beginning tutorial.
Browse to your development environment on port of 3000, e.g.
http://server.example.com:3000 to see the working app.
Troubleshooting - If you are having trouble displaying the page first be sure that you have restarted your rails server after editing
config/routes.rb. While any files in the
appdirectory can be edited and will reload automatically,
configfiles require a rails server restart. If you are still having trouble, please email us or contact us via our Slack channel with details about the issue and any error message(s) you see. Please remember to filter out any PHI when sharing.