Coder Social home page Coder Social logo

survey's Introduction

Survey

Build Status Code Climate

Surveys on Rails...

Survey is a Rails Engine that brings quizzes, surveys and contests into your Rails application. Survey models were designed to be flexible enough in order to be extended and integrated with your own models. Survey was initially extracted from a real application that handles contests and quizzes.

Documentation

You can view the Survey documentation in RDoc format here:

http://rubydoc.info/github/runtimerevolution/survey/frames

Demo App

We have implemented a demo app for you to try out: Demo App

Here is the repository: https://github.com/runtimerevolution/survey-demo

Main Features:

  • Surveys can limit the number of attempts for each participant
  • Questions can have multiple answers
  • Answers can have different weights
  • Base Scaffold Support for Active Admin, Rails Admin and default Rails Controllers
  • Base calculation for scores
  • Easy integration with your project

Installation

Add survey to your Gemfile:

gem "survey", "~> 0.1"

Then run bundle to install the Gem:

bundle install

Now generate and run migrations:

rails generate survey:install

bundle exec rake db:migrate

Getting started with Survey

Survey inside your models

To make a model aware of you just need to add has_surveys on it:

class User < ActiveRecord::Base
  has_surveys

  #... (your code) ...
end

There is the concept of participant, in our example we choose the User Model. Every participant can respond to surveys and every response is registered as a attempt. By default, survey logic assumes an infinite number of attempts per participant but if your surveys need to have a maximum number of attempts you can pass the attribute attempts_number when creating them.

# Each Participant can respond 4 times this survey
Survey::Survey.new(:name => "Star Wars Quiz", :description => "A quiz about Star Wars", :attempts_number => 4)

Surveys used in your controllers

In this example we are using the current_user helper but you can do it in the way you want.

class ContestsController < ApplicationController

  helper_method :survey, :participant

  # create a new attempt to this survey
  def new
    @attempt = survey.attempts.new
    # build a number of possible answers equal to the number of options
    survey.questions.size.times { @attempt.answers.build }
  end

  # create a new attempt in this survey
  # an attempt needs to have a participant assigned
  def create
    @attempt = survey.attempts.new(params[:attempt])
    # ensure that current user is assigned with this attempt
    @attempt.participant = participant
    if @attempt.valid? and @attempt.save
      redirect_to contests_path
    else
      render :action => :new
    end
  end

  def participant
    @participant ||= current_user
  end

  def survey
    @survey ||= Survey::Survey.active.first
  end
end

Survey inside your Views

Controlling Survey availability per participant

NOTE: avaliable_for_participant? method has been deprecated. Please use available_for_participant? method instead.

To control which page participants see you can use method available_for_participant? that checks if the participant already spent his attempts.

<% if @survey.available_for_participant?(@participant) %>
  <%= render 'form' %>
<% else %>
  Uupss, <%= @participant.name %> you have reach the maximum number of
  attempts for <%= @survey.name %>
<% end %>

<% # in _form.html.erb %>
<%= form_for [:contests, @attempt] do |f| %>
  <%= f.fields_for :answers do |builder| %>
    <ul>
      <% @survey.questions.each do |question| %>
        <li>
          <p><%= question.text %></p>
          <%= builder.hidden_field :question_id, :value => question.id %>
          <% question.options.each do |option| %>
            <%= builder.check_box :option_id, {}, option.id, nil %>
            <%= option.text %> <br/ >
          <% end -%>
        </li>
      <% end -%>
    </ul>
  <% end -%>
  <%= f.submit "Submit" %>
<% end -%>

Scaffolds and CRUD frameworks

If you are using Rails Admin or Active Admin, you can generate base CRUD screens for Survey with:

rails generate survey active_admin

rails generate survey rails_admin

If you want a simple way to get started you can use the plain option which is a simple Rails scaffold to generate the controller and views related with survey logic. By default when you type rails g survey plain it generates a controller in the admin namespace but you can choose your own namespace as well:

rails generate survey plain namespace:contests

By default when you generates your controllers using the plain command the task generates the associated routes as well. Afterwards if you want to generate more routes, you can using the command:

rails generate survey routes namespace:admin

How to use it

Every user has a collection of attempts for each survey that they can respond to. Is up to you to make averages and collect reports based on that information. What makes Survey useful is that all the logic behind surveys is now abstracted and well integrated, making your job easier.

Hacking with Survey through your Models:

# select the first active Survey
survey = Survey::Survey.active.first

# select all the attempts from this survey
survey_answers = survey.attempts

# check the highest score for current user
user_highest_score  = survey_answers.for_participant(@user).high_score

#check the highest score made for this survey
global_highest_score = survey_answers.high_score

Compability

Rails

Survey supports Rails 3 and 4. For use in Rails 4. Rails 4 support is recent, so some minor issues may still be present, please report them.

Active Admin

Only support versions of Active Admin higher than 0.3.1.

Roadmap

  • Add a form builder or a helper to improve the creation of Survey forms.
  • Add polymorphic relations to help the survey be extended with subclasses.
  • Allow adding new fields without breaking the existent logic.

License

Copyright © 2013 Runtime Revolution, released under the MIT license.

survey's People

Contributors

alex-quiterio avatar chukitow avatar jduarte avatar jgorset avatar juliawong avatar nblake989 avatar risinglf avatar rjst avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

survey's Issues

DB Migration Error

Hi ,

Please suggest the solution for Db migration error.

  • create_table(:survey_surveys)
    -> 0.0838s
    -- create_table(:survey_questions)
    rake aborted!
    StandardError: An error has occurred, this and all later migrations canceled:

PG::UndefinedTable: ERROR: relation "surveys" does not exist
: CREATE TABLE "survey_questions" ("id" serial primary key, "survey_id" integer, "text" character varying(255), "created_at" timestamp, "updated_at" timestamp, CONSTRAINT fk_survey_questions_survey_id FOREIGN KEY ("survey_id") REFERENCES "surveys" ("id")) /home/test/db/migrate/20150515142125_create_survey.rb:15:in up' ActiveRecord::StatementInvalid: PG::UndefinedTable: ERROR: relation "surveys" does not exist : CREATE TABLE "survey_questions" ("id" serial primary key, "survey_id" integer, "text" character varying(255), "created_at" timestamp, "updated_at" timestamp, CONSTRAINT fk_survey_questions_survey_id FOREIGN KEY ("survey_id") REFERENCES "surveys" ("id")) /home/test/db/migrate/20150515142125_create_survey.rb:15:inup'
PG::UndefinedTable: ERROR: relation "surveys" does not exist
/home/test/db/migrate/20150515142125_create_survey.rb:15:in `up'
Tasks: TOP => db:migrate
(See full trace by running task with --trace)

Thank you !

rails 4 protected attributes

In app/models/survey/attempt at line 14 -- calling

attr_accessible :participant_id, :survey_id,
:answers_attributes, :survey, :winner, :participant

Does this need to be

def attempt_params
params.require(:attempt).permit(:participant_id, :survey_id,
:answers_attributes, :survey, :winner, :participant)
end

Sorry, bit of a noob at rails

Routes are not generated

I used "rails generate survey active_admin", but routes are not generated nor controllers.
Ps: Activeadmin gem is already installed

Fix generated scaffolds

@Survey should be pluralized according to views

  def index
    @survey = Survey::Survey.all
  end

Using your namespaced scaffold-generation:
rails g survey plain namespace:tools

results in _form-partial:
undefined method `tools_survey_survey_path' for #<#Class:0x8e21ae8:0x66743a0>

I don't know this *_scope-methods used there. Is this rails-stuff oder something defined by you ? <%= form_for survey_scope(@Survey) do |f| %>

In general: Editing surveys does not persist changes if I add new options or questions.
Nothing really dramatically ... they are just scaffolds. I can write them myself.

Plain generation not creating routes

Rails 4:

Rails generate survey plain is not creating the necessary routes. Rails generate survey routes did not do it either. I had to manually add it to make it work.

ragarding creating a quiz app in rails

hi guyz i am new in ror and i creating a quiz app which is cient project i want one question on one page how can i achieve this if anybudy knows plz help me
thanks
jass

ragarding creating a quiz app in rails

hi guyz i am new in ror and i creating a quiz app which is cient project i want one question on one page how can i achieve this if anybudy knows plz help me
thanks

Migration fails

Hi

Migrating to CreateSurvey (20140903155504)
(0.1ms) BEGIN
== 20140903155504 CreateSurvey: migrating =====================================
-- create_table(:survey_surveys)
(19.5ms) CREATE TABLE "survey_surveys" ("id" serial primary key, "name" character varying(255), "description" text, "attempts_number" integer DEFAULT 0, "finished" boolean DEFAULT 'f', "active" boolean DEFAULT 'f', "created_at" timestamp, "updated_at" timestamp)
-> 0.0232s
-- create_table(:survey_questions)
(1.5ms) SELECT f.conname, pg_get_constraintdef(f.oid), t.relname
FROM pg_class t, pg_constraint f
WHERE f.conrelid = t.oid
AND f.contype = 'f'
AND t.relname = 'survey_questions'
AND t.relnamespace IN (SELECT oid FROM pg_namespace WHERE nspname = ANY (current_schemas(false)) )

(13.8ms) CREATE TABLE "survey_questions" ("id" serial primary key, "survey_id" integer, "text" character varying(255), "created_at" timestamp, "updated_at" timestamp, CONSTRAINT fk_survey_questions_survey_id FOREIGN KEY ("survey_id") REFERENCES "surveys" ("id"))
PG::UndefinedTable: ERROR: relation "surveys" does not exist
: CREATE TABLE "survey_questions" ("id" serial primary key, "survey_id" integer, "text" character varying(255), "created_at" timestamp, "updated_at" timestamp, CONSTRAINT fk_survey_questions_survey_id FOREIGN KEY ("survey_id") REFERENCES "surveys" ("id"))
(0.2ms) ROLLBACK
rake aborted!
StandardError: An error has occurred, this and all later migrations canceled:

PG::UndefinedTable: ERROR: relation "surveys" does not exist
: CREATE TABLE "survey_questions" ("id" serial primary key, "survey_id" integer, "text" character varying(255), "created_at" timestamp, "updated_at" timestamp, CONSTRAINT fk_survey_questions_survey_id FOREIGN KEY ("survey_id") REFERENCES "surveys" ("id")) /home/empire/rails4-starterkit/db/migrate/20140903155504_create_survey.rb:15:in up' ActiveRecord::StatementInvalid: PG::UndefinedTable: ERROR: relation "surveys" does not exist : CREATE TABLE "survey_questions" ("id" serial primary key, "survey_id" integer, "text" character varying(255), "created_at" timestamp, "updated_at" timestamp, CONSTRAINT fk_survey_questions_survey_id FOREIGN KEY ("survey_id") REFERENCES "surveys" ("id")) /home/empire/rails4-starterkit/db/migrate/20140903155504_create_survey.rb:15:inup'
PG::UndefinedTable: ERROR: relation "surveys" does not exist
/home/empire/rails4-starterkit/db/migrate/20140903155504_create_survey.rb:15:in `up'
Tasks: TOP => db:migrate
(See full trace by running task with --trace)

Seems odd, any suggestions?

Conditional questions

Hi would be great add support for show/hide questions depending of previous answer.

undefined method in the form

Using the Contests controller example, I'm going to add a simple correction for the controller, because it throws an undefined method 'base_class'. I've solved it by adding this:

class ContestsController < ApplicationController

  helper_method :survey, :participant

  # create a new attempt to this survey
  def new
    @participant = current_user #notice this and the base_class error disappears
    @attempt = survey.attempts.new
    # build a number of possible answers equal to the number of options
    survey.questions.size.times { @attempt.answers.build }
  end

  # create a new attempt in this survey
  # an attempt needs to have a participant assigned
  def create
    @attempt = survey.attempts.new(params[:attempt])
    # ensure that current user is assigned with this attempt
    @attempt.participant = participant
    if @attempt.valid? and @attempt.save
      redirect_to contests_path
    else
      render :action => :new
    end
  end

  def participant
    @participant ||= current_user
  end

  def survey
    @survey ||= Survey::Survey.active.first
  end
end

But as I said before the 'base_class' error disappears and throws another error in the form.

<%= form_for [:contests, @attempt] do |f| %>  <!-- the error is this line it says 'undefined method for contest_survey_attemps_path' -->
  <%= f.fields_for :answers do |builder| %>
    <ul>
      <% @survey.questions.each do |question| %>
        <li>
          <p><%= question.text %></p>
          <%= builder.hidden_field :question_id, :value => question.id %>
          <% question.options.each do |option| %>
            <%= builder.check_box :option_id, {}, option.id, nil %>
            <%= option.text %> <br/ >
          <% end -%>
        </li>
      <% end -%>
    </ul>
  <% end -%>
  <%= f.submit "Submit" %>
<% end -%>

I'm using Rails 4

initializer for rails-admin does not work

Models won't get added. I had read anywhere that using c.model is deprecated, but I'm not sure. However it does not work this way. They are using now whitelists and blacklists for specifying the included models via 'config.included_models'. You should recap a remove of this initializer cause it's confusing. By the way: nice gem !

Generate routes for example controllers

We are not generating routes for example controllers. It makes sense to add them to the default task in order to the generated controllers be capable to work out of the box.

strong parameters for active admin

Update the active admin file (notice the comments in the code).
here is my example:

ActiveAdmin.register Survey::Survey do
  permit_params :name, :attempts_number, :description, :finished, :active #mandatory for rails 4 and newer versions of active admin
  menu :label => I18n.t("surveys")

  filter  :name,
          :as => :select,
          :collection => proc {
              Survey::Survey.select("distinct(name)").collect { |c|
                [c.name, c.name]
              }
          }
  filter :active #,
         #:as => :select,
         #:collection => ["true", "false"]
         # no needed activeadmin detects a boolean as yes or not automatically

  filter :created_at

  index do
    column :name
    column :description
    column :active
    column :attempts_number
    column :finished
    column :created_at
    actions #default_actions
  end

  form do |f|
    f.inputs I18n.t("survey_details") do
      f.input  :name
      f.input  :description
      f.input  :active #, :as => :select, :collection => ["true", "false"] no needed activeadmin detects a boolean input as checkbox
      f.input  :attempts_number
    end
    f.inputs I18n.t("questions") do
      f.has_many :questions do |q|
        q.input :text
        q.has_many :options do |a|
          a.input  :text
          a.input  :correct
        end
      end
    end
    f.actions #buttons
  end

end

There is another thing, the questions are not saving correctly, you can create a survey but when you save it, the questions were not saved, or when you try to save the survey a validation says " Survey without questions cannot be activated" in the active field and the questions that you've made, disappeared

I'm using active admin 1.0.0 pre 4
Rails 4.2.6
Ruby 2.20
the gsurvey gem "survey", "~> 0.1"

Mongoid

do you support mongoid in this gem?

rails generate survey rails_admin exception

Hello,

When I try to run the rails generate for RailsAdmin I'm getting this exception. I'm trying to add this to an existing site. Rails 4.2.2.

/.rbenv/versions/2.2.0-dev/lib/ruby/gems/2.3.0/gems/survey-0.2/lib/generators/survey/survey_generator.rb:87:in `get_scope': undefined method `split' for nil:NilClass (NoMethodError)

Thanks

session based

Hey guys,

I was wondering if it's possible to use the survey without binding it to a specific user. For example if I want to ask a visitor a question but he doesn't have an account yet.

Cezar

ActiveModel::ForbiddenAttributesError

Hey guys,

I was trying to create a survey at http://localhost:3000/contests/surveys/new and when I create the test I am running into a ActiveModel::ForbiddenAttributesError at /contests/surveys error and it is pointing to the first line in your Survey create. I can test my parms coming in and it looks ok to me so I am not sure what is going on.

FYI the parm incoming is

params[:survey_survey]
=> {"name"=>"test", "attempts_number"=>"100", "active"=>"true", "description"=>"testing", "questions_attributes"=>{"1389644195139"=>{"text"=>"q1", "options_attributes"=>{"1389644204233"=>{"text"=>"right", "correct"=>"1", "_destroy"=>"false"}, "1389644214822"=>{"text"=>"wrong", "correct"=>"0", "_destroy"=>"false"}}, "_destroy"=>"false"}}}

Thanks,

activemodel forbiddenattributeserror

Attach a Survey to a parent Model

How you would attach a survey model to another model that acts as its parent?

Eg:

A lesson has a survey
The survey belongs to the lesson (or anything)

Bundling Issues on Windows Platform

getting error when trying to bundle install on windows env:

Unable to create file rdoc/<.html (Invalid argument) when running bundle install with gem 'survey'

How to use the form-partial for attempts ?

Hi again, maybe I do something wrong but currently I can't get the form-partial running. I have a survey with two questions. The new-action in the AttemptsController prepares answers on attempts n-times for each question. However, this causes that all questions will be shown n-times because <%= f.fields_for :answers do |builder| %> renders the ul-tag n-times ?!

Issue 2: Each question has 5 options for answering, but only the last selected option will be in the params-hash. I have to change the checkbox like this:
<%= builder.check_box :option_id, {multiple: true}, option.id, nil %>

For what kind of use-case did you provided this form-partial? I think for my case I could never get this working or am I wrong ?

Survey response types

Hello!

Using this gem, is it possible to create non-multiple choice questions (ie, just a text area for users to write things)? Or do all the questions have to be multiple choice?

Thanks!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.