The NUBIC/surveyor gem is an awesome ruby gem and developer tool that brings surveys into Rails applications. Surveys are written in the Surveyor DSL (Domain Specific Language). If your Rails app needs to asks users questions as part of a survey, quiz, or questionnaire then you should consider using Surveyor.
This tutorial is to help Rails beginners implement and extend this gem in their Rails project. The "kitchen sink" Survey in the surveyor README is a great place to get started, as is the "extending surveyor" README. However, for beginners, I thought it might be useful to have an example that walks through how to tie the surveyor gem to your user model and make some basic customizations. For this tutorial I am using Rails 3.2.3 and Ruby 1.9.3p125 (2012-02-16 revision 34643) [x86_64-darwin10.8.0].
#Surveyor Tutorial
###Section 1 - Create a new rails app and get the 'kitchen sink' survey working
-
Create a new repository on GitHub named 'surveyor_example'
-
Create a new rails project
$ rails new surveyor_example $ cd surveyor_example
-
Open the project in your favorite text editor (example: I am using Sublime Text 2)
$ subl .
-
Update the Gemfile. Cut & Paste the contents of this tutorials Gemfile into your Gemfile.
-
Install and include the new gems
$ bundle install
5a) In my case, my rake version is 0.9.2.2 and the surveyor gem requires 0.9.2, so I received the following error:
"You have requested: rake = 0.9.2 The bundle currently has rake locked at 0.9.2.2."
If this happens to you, run the following in your command line:
$ bundle update rake
-
Initialize the Git repository and push to GitHub
$ git init $ git add . $ git commit -m "Initial commit" $ git remote add origin git@github.com:/surveyor_example.git $ git push -u origin master
-
(Optional) Deploy the app to Heroku. (Assuming you have already created a Heroku account. If not, check out this tutorial)
$ heroku create --stack cedar $ git push heroku master
-
Generate surveyor assets
$ script/rails generate surveyor:install
-
Migrate the database (If you received the rake version error above, be sure to include 'bundle exec' before your rake command)
$ bundle exec rake db:migrate
-
Try out the 'kitchen sink' survey
$ bundle exec rake surveyor FILE=surveys/kitchen_sink_survey.rb
-
Test it on the local server (start the server)
$ rails s
And visit: http://localhost:3000/surveys
- Deploy and test it on Heroku
In the production.rb file (located in config/environments) set:
config.assets.compile = true
- this is due to open issue #307
Then, in the command line:
$ git add .
$ git commit -am "Installed surveyor assets"
$ git push
$ git push heroku
$ heroku run rake db:migrate
$ heroku run rake surveyor FILE=surveys/kitchen_sink_survey.rb
$ heroku open
Now navigate to http://[yourappname].herokuapp.com/surveys
you can visit the example for this tutorial here: http://surveyor-example.herokuapp.com/surveys
###Section 2 - Create your own survey
- Try making your own survey
Create a new file in the surveys folder of your project, name it 'my_survey.rb' and edit it as you like.
-
Parse the survey
$ bundle exec rake surveyor FILE=surveys/my_survey.rb
-
Try it on the local server
$ rails s
And visit: http://localhost:3000/surveys
-
Try it on Heroku
$ heroku run rake surveyor FILE=surveys/my_survey.rb $ heroku open
Now navigate to http://[yourappname].herokuapp.com/surveys
###Section 3 - Add a user model
-
Create a Users controller
$ rails generate controller Users new
-
Generate a User model
$ rails generate model User name:string email:string
-
Migrate the new model
$ bundle exec rake db:migrate
-
Add some basic validations to the User model
class User < ActiveRecord::Base attr_accessible :name, :email, :password, :password_confirmation has_secure_password
before_save { |user| user.email = email.downcase }
validates :name, presence: true, length: { maximum: 50 } VALID_EMAIL_REGEX = /\A[\w+-.]+@[a-z\d-.]+.[a-z]+\z/i validates :email, presence: true, format: { with: VALID_EMAIL_REGEX }, uniqueness: { case_sensitive: false } validates :password, length: { minimum: 6 } validates :password_confirmation, presence: true end
-
Add an index to the user email
$ rails generate migration add_index_to_users_email
-
Navigate to the db/migrate folder and open the file that was just created db/migrate/[timestamp]_add_index_to_users_email.rb and edit it like below
class AddIndexToUsersEmail < ActiveRecord::Migration def change add_index :users, :email, unique: true end end
-
Add password_digest to the model
$ rails generate migration add_password_digest_to_users password_digest:string
-
Migrate the database
$ bundle exec rake db:migrate
-
Open the rails console and create a new user
$ rails console
User.create(name: "Your Name", email: "yourname@example.com", ?> password: "foobar", password_confirmation: "foobar")
-
Commit the changes
$ git add . $ git commit -m "A basic User model" $ git push $ git push heroku
###Section 4 - Create a sign up and sign in form
- Add a Users resource to the routes file (config/routes.rb)
SurveyorExample::Application.routes.draw do
resources :users
match '/signup', to: 'users#new'
end
be sure to remove the line 'get "users/new"'
- Create a form to sign up new users
Edit this view: app/views/users/new.html.erb
You can copy the code from this example
-
Update the UsersController
class UsersController < ApplicationController def new @user = User.new end
def show @user = User.find(params[:id]) end
def create @user = User.new(params[:user]) if @user.save redirect_to @user else render 'new' end end
end
-
Add a page to show user info at app/views/users/show.html.erb
<%= @user.name %>, <%= @user.email %>
-
Generate a Sessions Controller
$ rails generate controller Sessions
-
Update the config/routes.rb file:
SurveyorExample::Application.routes.draw do resources :users resources :sessions, only: [:new, :create, :destroy]
match '/signup', to: 'users#new' match '/signin', to: 'sessions#new' match '/signout', to: 'sessions#destroy', via: :delete end
-
Add a new, create and destroy method to the SessionsController app/controllers/sessions_controller.rb
class SessionsController < ApplicationController def new end
def create end
def destroy end end
-
Create a signin view app/views/sessions/new.html.erb
<%= form_for(:session, url: sessions_path) do |f| %>
<%= f.label :email %> <%= f.text_field :email %>
<%= f.label :password %> <%= f.password_field :password %>
<%= f.submit "Sign in" %> <% end %>
-
Update the SessionsController
-
Update the ApplicationController
-
Generate remember token
$ rails generate migration add_remember_token_to_users
-
Add the remember token to the users table (db/migrate/[timestamp]_add_remember_token_to_users.rb)
class AddRememberTokenToUsers < ActiveRecord::Migration def change add_column :users, :remember_token, :string add_index :users, :remember_token end end
-
Migrate the database
$ bundle exec rake db:migrate
-
Update the user model
-
Add a SessionsHelper