Giter VIP home page Giter VIP logo

rapidfire's Introduction

Rapidfire

One stop solution for all survey related requirements! Its tad easy!

This gem supports:

  • rails: 4.2, 5.0, 5.1, 5.2, 6.0, 6.1 and 7.0
  • ruby: 2.4, 2.5, 2.6, 2.7, 3.0, 3.1 and 3.2

NOTE: Some combinations won't be supported. Please check CI for the ignored ones.

A simple implementaiton of this gem can be found at https://rapidfire.fly.dev. And the source code of application is https://github.com/code-mancers/rapidfire-app.

Installation

Add this line to application's Gemfile:

gem 'rapidfire'

And then execute:

$ bundle install
$ bundle exec rake rapidfire:install:migrations
$ bundle exec rake db:migrate

Rapidfire views can also be customized. This command copies the views into app/views directory:

$ bundle exec rails generate rapidfire:views

Rapidfire locales (i18n) files can also be customized. The command is:

$ bundle exec rails generate rapidfire:locales

Usage

Add this line to config/routes.rb file, thats good enough

mount Rapidfire::Engine => "/rapidfire"

Please point the browser to http://localhost:3000/rapidfire

All rapidfire controllers inherit from your ApplicationController. So define 2 methods current_user and can_administer? on your ApplicationController

  1. current_user : the user who is answering the survey. can be nil
  2. can_administer? : a method which determines whether current user can create/update survey questions.

Typical implementation would be:

class ApplicationController < ActionController::Base
  def current_user
    @current_user ||= User.find(session[:user_id])
  end

  def can_administer?
    current_user.try(:admin?)
  end
end

It also will assume that whatever current_user returns above will respond to a method called survey_name.

That method should return the name that is associated with the results. For example:

class User
  def survey_name
    "#{last_name}, #{first_name}"
  end
end

If the application is using authentication gems like Devise, Devise will automatically provide current_user helper for free. There is no need to define it

Override

Override path to redirect after answer the survey

# my_app/app/decorators/controllers/rapidfire/attempts_controller_decorator.rb
Rapidfire::AttemptsController.class_eval do
  def after_answer_path_for
    main_app.root_path
  end
end

Routes Information

Once this gem is mounted on, say at 'rapidfire', it generates several routes They can be listed by running bundle exec rake routes.

  1. The root_path i.e localhost:3000/rapidfire always points to list of surveys {they are called question groups}. Admin can manage surveys, and any user {who cannot administer} can see list of surveys.

  2. Optionally, each survey can by answered by visiting this path:

    localhost:3000/rapidfire/surveys/<survey-id>/attempts/new
    

    This url can be distributed so that survey takers can attempt the survey

  3. If you have an established application that uses route helpers and/or the url_for([@model1, @model2]) style, you can include your route helpers in RapidFire by adding config/initializers/rapidfire.rb with the following content:

    Rails.application.config.after_initialize do
      Rails.application.reload_routes!
    
      Rapidfire::ApplicationController.class_eval do
        main_app_methods = Rails.application.routes.url_helpers.methods
        main_app_route_methods = main_app_methods.select{|m| m =~ /_url$/ || m =~ /_path$/ }
        main_app_route_methods.each do |m|
          define_method m do |*args|
            main_app.public_send(m, *args)
          end
          helper_method m
        end
      end
    end

Survey Results

There is an API for fetching the results. This is not efficient, but is provided for the sake of quickly aggregating survey results

GET /rapidfire/surveys/<survey-id>/results

This new api supports two formats: html and json. The json format can be used with any javascript based chart solutions like Chart.js. An example can be seen here.

Diving into details of json format, all the questions can be categorized into one of the two categories:

  1. aggregatable: questions like checkboxes, selects, radio buttons fall into this category.
  2. non-aggregatable: questions like long answers, short answers, date, numeric etc.

All the aggregatable answers will be returned in the form of hash, and the non-aggregatable answers will be returned in the form of an array. A typical json output will be like this:

[
  {
    "question_type": "Rapidfire::Questions::Radio",
    "question_text": "Who is author of Waiting for godot?",
    "results": {
      "Sublime": 1,
      "Emacs": 1,
      "Vim": 1
    }
  },
  {
    "question_type": "Rapidfire::Questions::Checkbox",
    "question_text": "Best rock band?",
    "results": {
      "Led Zeppelin": 2
    }
  },
  {
    "question_type": "Rapidfire::Questions::Date",
    "question_text": "When is your birthday?",
    "results": ["04-02-1983", "01/01/1970"]
  },
  {
    "question_type": "Rapidfire::Questions::Long",
    "question_text": "If Apple made a android phone what it will be called?",
    "results": ["Idude", "apdroid"]
  },
  {
    "question_type": "Rapidfire::Questions::Numeric",
    "question_text": "Answer of life, universe and everything?",
    "results": ["42", "0"]
  },
  {
    "question_type": "Rapidfire::Questions::Select",
    "question_text": "Places you want to visit after death",
    "results": {
      "Iran": 2
    }
  }
]

How it works

This gem gives on the fly access to create questions under a survey. Once the survey is created, questions can be added to the survey. Every survey will have a url which can be can passed around to others to take the survey.

The typical flow about how to use this gem is:

  1. Create a survey by giving it a name.

  2. Once the survey is created, start adding questions to the survey

  3. Create a question by clicking on add new, and there will be several options Each question will have a type

    • Checkbox Create a question which contains multiple checkboxes with the options that you provide in answer options field. Note that each option should be on a separate line.
    • Date It takes date as an answer
    • Long It needs a description as answer. Renders a textarea.
    • Numeric It takes a number as an answer
    • Radio It renders set of radio buttons by taking answer options.
    • Select It renders a dropdown by taking answer options.
    • Short It takes a string as an answer. Short answer.
    • File It renders a file input which can take only 1 file.
    • MultiFile It renders a file input which can take multile files.
  4. Once the type is filled, optionally other details can be filled:

    • Question text What is the question?
    • Answer options Give options separated by newline for questions of type checkbox, radio buttons or select.
    • Answer presence Should you mandate answering this question?
    • min and max length Checks whether answer if in between min and max length. Ignores if blank.
    • greater than and less than Applicable for numeric question where answer is validated with these values.
  5. Once the questions are populated, a url will be created which can be shared

  6. Note that answers fail to persist if the criteria provided while creating the questions fail.

Notes on upgrading

Adding multitenancy support
$ rake rapidfire:upgrade:migrations:multitenancy
Upgrading from 2.1.0 to 3.0.0

Some table names have changed:

  • rapidfire_question_groups to rapidfire_surveys, and
  • rapidfire_answer_groups to rapidfire_attempts.

Run this rake task to do this change automatically

$ rake rapidfire:upgrade:migrations:from210to300
Upgrading from 1.2.0 to 2.0.0

The default delimiter which is used to store options for questions like select input, multiple answers for checkbox question is comma (,). This resulted in problems where gem is unable to parse options properly if answers also contain commas. For more information see issue-19.

Starting from version 2.0.0 default delimiter is changed to \r\n, but a configuration is provided to change the delimiter. Please run this rake task to make existing questions or stored answers to use new delimiter.

NOTE: Please take database backup before running this rake task.

bundle exec rake rapidfire:change_delimiter_from_comma_to_srsn
bundle exec rake rapidfire:change_delimiter_from_comma_to_srsn

If this change is not feasible rightaway, and the application needs to use comma as delimiter, then please use this initializer, but be warned that in future delimiter will be hardcoded to \r\n:

# /<path-to-app>/config/initializers/rapidfire.rb

Rapidfire.config do |config|
  config.answers_delimiter = ','
end

TODO

  1. Add ability to sort questions, so that order is preserved.

Contributing

  1. Fork it
  2. Create a feature branch (git checkout -b my-new-feature)
  3. Commit all the changes (git commit -am 'Add some feature')
  4. Push to the branch (git push origin my-new-feature)
  5. Create new Pull Request

rapidfire's People

Contributors

akshaysasidrn avatar altherlex avatar brunoocasali avatar cengiz7 avatar chukitow avatar codeodor avatar dawnmd avatar drernie avatar e3betht avatar emilsoman avatar gnufied avatar harshwardhansingh avatar iffyuva avatar juneyuzhujun avatar maclover7 avatar nadav-nite avatar pasta avatar siobhanjacobson avatar snkshukla avatar spilist avatar sujayprabhu96 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

rapidfire's Issues

Make controllers before_filter free.

This helps in deriving from controllers, and specifying them {refer to exp-multitenant-support branch}, and adding filters the way user wants. At present, there is one before_filter can_administer?, and its too difficult to add any filter before it. One can do skip_before_filter can_administer? and redefine before_filter sequence, but user should be given more control w.r.t controllers.

Survey association

Hello,

is it possible to not associate the survey with current_user, but instead with another model? How do I supply the model Id to the survey?

Thanks!

Override AnswerGroupsController#create to redirect to another page

Hi All,

At present, when someone completes the survey and clicks 'Save', it POSTs to AnswerGroupsController#create which ends in a redirect to question_groups_path.

What's your recommended way for overriding the default redirect_to in AnswerGroupsController#create to another page?

Thanks.

Feature Request: Easy way to add customized fields

I don't know if is possible in the actual state of the gem, or just add proper documentation to it.

For example a combined field to show:

Something: ________________ Date: __/__/____

  • Add Documentation
  • Add Tests
  • Add Proper Code

Thanks!

Order the questions

Hi all, I'm trying to order the questions by created_at and I cannot find the way to do it.
Any help please ?

Feature Request: Images as part of the question

Hi folks,
It would be really excellent if we could include images as part of the question? For instance

[Image]
Question: In this Venn Diagram the blue segment corresponds to what?

Any suggestions?

Thanks

reCaptcha or simply Captcha

Just wondering if there is any way to reduce spams by putting some challenge questions? What about reCaptcha?

Thank you.

Do you have question explanation in this gem?

I was wondering if you have someway to explain a question type. for example if the type is radio you say choose 1 if the type is checkbox choose 1 or more.
I didint see it maybe i overlooked? Did you build this in this gem?

Add option to change the name of method current_user

Allow changing the name of current_user method to any other, this can be requested at config file. Because sometime a SimpleUser will be answer the survey, and a AdminUser will create a survey. In this case what kind of this users will be the current?

Just add a section in config file, if is not set return :current_user yet!

Thanks!

Feature Request: Rubocop Stylish

  • Add to app the rubocop gem.
  • Add to Travis CI (broke PR's if it's not at the defaults).
  • Fix all app offences according with rubocop.

Acts_as_surveyable?

Hi,
This is a support request, not an issue, because I am trying to understand whether rapidfire will do what I need.

As I understand it we have surveys, which are a bunch of questions, and an answer group which is a particular user's attempt to answer those questions. What I want is for a survey (and thus answer group of responses to that survey) to be associated with an arbitrary model, rather than users as a whole.

For instance, imagine that we had a bunch of questions about a movie you just watched .I might ask the same questions about lots of movies, and not just one.

One possibility is that we include the id of the movie as an answer to a question that users cannot change. That would also require a model id to be an acceptable answer, but one which is specified by the server, not the user. I can't see that in the current list of types.

Does anyone do this?

Thanks

retrieve individual users survey responses

I know we can get the aggregate responses from all users for a given survey (by this: GET /rapidfire/question_groups//results)

But is there a way to retrieve an individual users responses to a survey?

Thanks!

cleanup migrations

right now we have migrations which try to preserve history. get rid of these migrations and write generators for migrations so that new users won't be confused. and write instructions for existing users to migrate to new schema.

undefined method `each' for nil:NilClass with empty radiobuttons save

If answers variants have only radiobuttons and not selected any, after Save we have "undefined method `each' for nil:NilClass" here:

    def save!(options = {})
      params.each do |question_id, answer_attributes|
        if answer = @answer_group.answers.find { |a| a.question_id.to_s == question_id.to_s }
          text = answer_attributes[:answer_text]

add support to filter results based on answers provided

requirement from anil

right now we show results including all answers. we should be able to filter results based on answers provided.

eg:

  • say there is a radio input question "Gender".
  • and another free form text question "Name"
  • now bunch of people answered these two questions.
  • admin should be able to filter survey results based on gender.

Position is missing for QuestionForm

The Question model has a position attribute. This attribute is missing in the QuestionForm therefore it can not be added to the questions/form view.

Routing

I have an issue were I have links for my differents controllers of my app and for the rapidfire index on application.html.erb; the links work good when I'm in my controllers links, but when I go to the rapidfire path i get undefined local variable or method 'mymodel_path' is there a clean way to fix this?

Can I access results by saying @user.surveys?

I'd like a way to load an individuals set of survey results. Better yet, I'd like to be able to specify the survey and user and see the results. Perhaps @user.survey(survey_id) ?

after attempt redirect

Hi all,
How about adding a config option for 'after_attempt_path' - that sets the url to redirect to, after a successful attempt creation.
In PR#74 this is done using a decorator, but maybe it is easier for the integrating app to set this value in an initializer file. Something like this

#Maip app : config/initializers/rapidfire_init.rb
Rapidfire.config do | config |
config.after_attempt_path = "/login"
end

Rails 4 issue

Hi there,

I'm facing the mass assignment protection error behaviour that follows here : http://pastebin.com/19RTABLW

For now i've polluted models with attar_accessible by changing the if statement with : Rails::VERSION::MAJOR >= 3 ...
... but it has been told that is not a long term fix =)

I could also have config.active_record.whitelist_attributes set to false configured in application.rb but it might be a good idea to be compliant with it the normal behavior.
Any help in order to fix this one would be grateful =)

Regards,

Regis A. Despres

Ability to add custom question type?

To be very specific I was thinking of having rating type of question which will just have different layout than radio buttons. Thanks. How do you propose I should proceed?

Use two types in one question?

Hi
I was wondering if you can use 2 types of answers for 1 question. If i have a question with checkboxes and a short text field if the answer they are looking for is not in the checkboxes?

I hope my question is clear. if its not please tell me.

will 1.1 support rails 4?

I see commits related to rails4. Wondering if you plan an RC build and/or if 1.1 will have full rails4 support?

Nice library. Cheers.

add support for conditional inputs

requested by anil.

usecase:

  • say if i have a dropdown with countries "india", "us", and
  • subsequent dropdown is states. then this question is first question.

Rails 5.1: Index Creation fails

I kept getting errors on 'db:migrate' like:

-- add_index(:rapidfire_questions, :survey_id)
rake aborted!
StandardError: An error has occurred, this and all later migrations canceled:

Index name 'index_rapidfire_questions_on_survey_id' on table 'rapidfire_questions' already exists

I ended up commenting out all the add_index lines.

API support

Hello, I'm using a forked version of this repository, and now I'm needing it to have a API support, so we are going to implement it, so any suggestions on how we could do this to contribute to this project ?

Question text as a label

Hi all,
The question text is rendered in the different answers partials using a common instruction:

<%= f.label :answer_text, answer.question.question_text %>

This results in a markup that looks like

<label for="attempt_1_answer_text">How are you ?</label>

This is a bit weird since there is no accompanying input element named 'attempt_1_answer_text'.
Also this label does not contain any answer text but rather a question text.

Maybe this label should be replaced by a span or a div element, with a more descriptive id attribute.

paginate

I was wondering if its possible to paginate the surveys?
whats the smart way is to approach this ?

Commas used in answers cause problems with results calculations

If you use a comma within an answer it causes a problem with results.
for example, If my answer is "no, that is not right" the results will tabulate 1:"no" and 1:"that is not right"
I think the answers are being counted by splitting on a comma which leads to this problem. Not sure how to fix it.

Rapidfire installation failing

When I run 'bundle exec rake rapidfire:install:migrations'

I recieve the following error:

rake aborted!
Don't know how to build task 'railties:install:migrations'
/root/.rvm/gems/ruby-2.1.1@global/gems/railties-3.2.17/lib/rails/engine.rb:611:in block (4 levels) in <class:Engine>' /root/.rvm/gems/ruby-2.1.1/bin/ruby_executable_hooks:15:ineval'
/root/.rvm/gems/ruby-2.1.1/bin/ruby_executable_hooks:15:in `

'
Tasks: TOP => rapidfire:install:migrations

Have you seen this issue before?

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.