Census: Rails Demographics Collection

4.16.10 by Mark Kendall

Much like the United States government, your Rails application may need to collect demographics data for each of its users. That’s where the Census gem comes in. It’s a Rails engine that provides:

  • an administration interface for defining the data you’d like to collect
  • extensions on your User model and forms for collecting users’ responses
  • a simple way to search for users based on their responses

In this post, we’ll take a look at Census by extending a simple Rails app to include a user satisfaction survey.

Getting Started

Before we can look at Census, we’ll need to create a sample Rails app to work with. Start by creating a Rails app called survey with a scaffold for your User model.

rails survey
cd survey
script/generate scaffold user name:string email:string
rake db:migrate

After you’ve done this, start your development server, navigate to http://localhost:3000/users and create a user. Note that in a real application we’d want to have an authentication system that requires users to sign up and log in. For this example we simply need a User model object, so the scaffold we just generated is sufficient. Check out Blue Light Special if you’d like to expand this example to include a real authentication system.

Installing Census

Start by installing the census gem, running its generator, and migrating the database.

gem install census
script/generate census
rake db:migrate

Edit config/environment.rb to require the census gem.

config.gem 'census'

Census requires jQuery and provides a stylesheet, so let’s include those in app/views/layouts/application.html.erb.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
       "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
  <%= javascript_include_tag 'http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js' %>
  <%= javascript_include_tag 'http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.2/jquery-ui.min.js' %>
  <%= javascript_include_tag 'census' %>
  <%= stylesheet_link_tag 'census' %>
</head>
<body>

<%= yield %>

</body>
</html>

You’ll probably want to take a look at the various configuration options for Census in config/initializers/census.rb. That’s the place to look if you’d like to define custom data types or restrict access to the Census administration UI. For this example, we’re going to stick with the default configuration.

Defining the Data to Collect

Now that Census is configured, fire up your web server and go to http://localhost:3000/census/admin. You’ll see a simple interface for setting up the demographics data you’d like to collect. Questions are organized into Data Groups, so go ahead and create a new Data Group. We’ll call the group Feedback and add two questions:

You can rearrange the questions and answers using drag and drop. We’ve supplied four possible answers for the first question, so our users will see a select box with those options. Since we haven’t included any answer choices for the second question, census will render a text field that allows the user to enter any number. Feel free to add more questions if you’d like. Hit Save when you’re done, and you’re ready to display questions and answers in your user views.

Collecting Answers from Users

The User scaffold we generated earlier built an edit form for our user in app/views/users/edit.html.erb, so let’s add our Census questions to that form. All we need to do is render the census/user_questions partial somewhere in our form, passing it the user. I added this just above the submit button:

<%= render 'census/user_questions', :user => @user %>

Navigate to http://localhost:3000/users/1/edit and you’ll see that your Census questions are included in the form.

You can also render the census/user_answers partial anywhere you’d like to see a user’s answers. I included it at the bottom of app/views/users/show.html.erb:

<%= render 'census/user_answers', :user => @user %>

Searching for Users

Now that we’re collecting answers from our users, we’d like to be able to search for users whose answers match certain values. Census provides a search capability that allows us to do just that. There’s no UI provided for this, so we’ll fire up the Rails console and look at a few examples.

First, we need to look up the Question objects that we want to search against:

satisfied = Question.find_by_prompt('How satisfied are you with this app?')
logins_per_week = Question.find_by_prompt('How many times per week do you log in?')

Now, we can find all the users who are very satisfied:

users = Census::Search(satisfied => 'Very Satisfied').perform

Or all the users who log in between 5 and 10 times per week:

users = Census::Search(logins_per_week => 5..10).perform

Or all the users who are indifferent or hate our app and log in less than 2 times per week:

users = Census::Search(satisfied => ['Indifferent', 'I Hate It'], logins_per_week => 0..2).perform

The Census search object allows you to pass single values, arrays, or ranges as search criteria. It will find users that match all of the criteria provided.

Future Development

Census is being used in several of our projects at Envy Labs, and we have plans to add more features soon. These include support for:

  • additional data types
  • custom partials for rendering questions and answers
  • compound questions that include multiple form fields

If you have other suggestions or ideas, let us know. Or, fork the project on github and start hacking!

Photo credit: The Census by quinnanya

Related posts:

  1. Getting Started with the Rails 3 BugMash
  2. The Rails State Machine
  3. Scaling Rails – On The Edge – Part 3

14 Responses to “Census: Rails Demographics Collection”

Comments

  1. Sohan says:

    I have linked this post at the Drink Rails blog.

  2. [...] at Envylabs, they announced a new gem called Census, which allows you to gather demographic-style data on your users and then search for data based on [...]

  3. John says:

    Does this not work with Rails 3?

    bash-3.2$ rails generate census
    Could not find generator census.

  4. Mark Kendall says:

    John: You’re correct. Census is not Rails 3 compatible today. We’re currently working on Rails 3 compatibility for all of our open source projects, and I expect that we’ll have a Rails 3 branch of census soon.

  5. [...] anyone) – good reading, and will improve my Rspec code a lot (tags: bdd rspec ruby testing) Census: Rails Demographics Collection « Envy Labs Sounds like something that can be used in a variety of projects (tags: admin interface plugin rails [...]

  6. Maho says:

    I’m having this error after rake db:migrate

    rake aborted!
    uninitialized constant Census

    any clue?

  7. Maho says:

    got it!

    I needed to first add the gem into the environment.rb and then run rake db:migrate.

    thks anyway!

  8. [...] to give your clients the ability to create different types of forms or surveys. This is where the Census gem comes in, providing an admin interface for creating forms, and even the ability to search through [...]

Leave a Reply

* Required Fields

Additional comments powered by BackType