Advertisement

Build a jQuery Mobile Survey App: Rails Setup

by
Student iconAre you a student? Get a yearly Tuts+ subscription for $45 →

Welcome to part I of the tutorial series on creating a quiz or survey app with jQuery Mobile and Rails. This series will demonstrate how to build a mobile compatible web application that will allow users to answer a series of questions in a wizard like fashion.

jQuery Mobile contains several useful, out-of-box features for making our web application usable on a variety mobile devices. In most cases, the basic template and CSS themes that come with jQuery Mobile will be sufficient. However, since all of the templating is done in CSS, we can customize the look and feel of our site pretty easily.

jQueryMobile is an ideal framework choice when building a mobile web application for many reasons, including:

1) Since the framework is built upon jQuery, there is a small learning curve for anyone who has used jQuery on the web.

2) It's currently compatible with many major platforms including: iOS, Android, Blackberry, Palm WebOS, Nokia/Symbian, Windows Mobile, etc.

3) The compressed size of the included libraries is approximately 12k which is very lightweight for the capabilities offered.

For the backend, we will be using Rails 3 with a few gems, including Typus.

To start, lets create a new rails app:

rails new .

Make sure you have the latest version of the rails gem installed. If you have any apps you are developing that require Rails 2, I suggest you research and install RVM (Ruby Version Manager). This will save you many headaches that can be caused by gem versioning issues.

Next, lets add our gems to our Gemfile:

source 'http://rubygems.org'

gem 'rails', '3.0.7'
gem 'sqlite3-ruby', :require => 'sqlite3'
gem 'jquery-rails'

# Admin
gem 'typus', :git => 'http://github.com/fesplugas/typus.git'
gem 'acts_as_list'

As you can see, we will be using Rails 3.0.7 as it is the latest stable version of Rails as of this writing. We'll also be overriding the default Prototype JS libraries that come with Rails by installing the jquery-rails gem. Since jQueryMobile will obviously require the jQuery base library, then we really don't have any reason to keep the included Prototype libraries around.

For our admin section, we will install the Typus gem and acts_as_list. With just a small amount of configuration, Typus will provide an entire backend for managing the questions we will create for our survey. Acts as list works seamlessly with Typus and will allow us to easily control the order of our questions.

Now we can run the bundler to install our gems:

bundle install

Both the jQuery gem and the Typus gem have generators that work to essentially have the gems install themselves. This is accomplished by running the following commands while in the app directory:

rails generate jquery:install
rails generate typus

By default, Typus comes without any sort of authentication gate. Since this is almost like direct access to the database, we should secure it as a first step. The simplest method of securing it will be to add basic http auth. This is obviously not hyper secure, but for the purposes of our tutorial it will suffice. In order to do this, we need to add the following lines to the config/initializers/typus.rb file:

config.admin_title = "survey"
config.authentication = :http_basic 
config.username = "admin"
config.password = "pass"

This will prompt the user to enter a username and password when the /admin URL is accessed.

Now that our app is fully setup, we can start generating our resources and database schema. We can use the Rails shorthand method of doing this right from the command line with the following:

rails generate resource question question:string position:integer

rails generate resource choice choice:string question_id:integer

rails generate resource answer question_id:integer choice_id:integer

rake db:migrate

We now have 3 tables in our database. One will house the questions we are going to ask the user. Each question will have many choices, and an answer will be a record storing the combination of I.D.s for a question and a choice. Since choices will only have one question, the question_id field in the answers table is not really necessary. We are going to put it here as an easy accessor for simplifying queries such as pulling the number of answers for a question. The position field in the questions table will allow us to specify the order of questions as they will appear in our survey.

To add these relationships to our models, we will modify them as follows:

/app/models/question.rb

class Question < ActiveRecord::Base
  acts_as_list
  has_many :choices
end

As you can see above, we are adding the acts_as_list plugin to this model so that we can alter the order of appearance for each question in our survey.

/app/models/choice.rb

class Choice < ActiveRecord::Base
  belongs_to :question
end

/app/models/answer.rb

class Answer < ActiveRecord::Base
  belongs_to :question
  belongs_to :choice
end

Done! Now that our resources and database tables have been generated, we need to create some controllers namespaced under an admin folder for Typus. To do this we run the following commands:

rails generate controller admin/answers
rails generate controller admin/choices
rails generate controller admin/questions

Next, we need to change the first lines in each of our controller files to make the controller inherit from ResourcesController instead of our base ApplicationController. In Typus, once we inherit from ResourcesController, we get some powerful CRUD functionality out of the box without having to write any further code. Below are the necessary replacements:

/app/controllers/admin/answers_controller.rb

replace:

class Admin::AnswersController < ApplicationController

with:

class Admin::AnswersController < Admin::ResourcesController

/app/controllers/admin/choices_controller.rb

replace:

class Admin::ChoicesController < ApplicationController

with:

class Admin::ChoicesController < Admin::ResourcesController

/app/controllers/admin/questions_controller.rb

replace:

class Admin::QuestionsController < ApplicationController

with:

class Admin::QuestionsController < Admin::ResourcesController

Almost there! Now we need to add some configuration statements to our Typus configuration file. If there are any other yaml files located in the config/typus directory, we can delete them because they are not necessary. Typus likely created sample configuration files when we ran our generator statement. Let's create a file called typus.yml located here: config/typus

First, we'll add the configuration statements for the Choice model:

Choice:
  fields:
    default: choice, question_id, question
    form: choice, question_id, question
  order_by: 
  relationships: question
  filters: created_at, question
  search: 
  application: survey

Question:
  fields:
    default: question, position
    form: question
  order_by: position
  relationships: choices
  filters: created_at
  search: question
  application: survey

Let's break this down:

Choice:
  fields:
    default: choice, question_id, question
    form: choice, question_id, question

In just a few lines of configuration, Typus will create a great deal of backend functionality for us. To start, we will specify the fields that we are allowed to edit. The default section of the fields definition will allow us to set which fields will be displayed in our list. In this case, it is the same set of fields that we will allow our admin to set in our create and update forms. This is specified in the form section of the fields definition.

order_by:

By default our choices will be ordered in the order they are created, so we don't need to specify anything for order_by.

relationships: question

Each choice belongs to one question, so we can define a relationship of question to our choice model. Typus will automagically design our forms to account for how data records relate to one another.

filters: created_at, question

Filters can be defined in typus simply by listing fields and/or relationships in the filters definition. Based on the field type, typus will create filter functionality in the backend. In the case of created_at, this will be a set of drop downs to specify a date. For question, this will be a drop down of all the questions stored in the database.

search: 
application: survey

The search definition is of no use to us for this model as we will unlikely be searching for any choices. Had we specified fields here though, typus would provide us a search box so we could filter the records stored in our DB by a search term. The application definition here is the name of the application our models are under which we are calling "survey."

As a final clean up step let's remove the file public/index.html which is going to block our default route.

Now we can start our server:

rails s

Visit the following URL in your browser to test out our newly created admin:

http://localhost:3000/admin

Next Time. . .

This concludes part I of our tutorial series on creating quiz or survey app in Rails and jQueryMobile. Stay tuned for part II where we will implement our jQueryMobile frontend.

Advertisement