rapidfire 4.0.0 → 5.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (217) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +120 -96
  3. data/app/assets/config/manifest.js +3 -0
  4. data/app/controllers/rapidfire/application_controller.rb +6 -2
  5. data/app/controllers/rapidfire/attempts_controller.rb +2 -2
  6. data/app/controllers/rapidfire/questions_controller.rb +1 -1
  7. data/app/controllers/rapidfire/surveys_controller.rb +30 -13
  8. data/app/helpers/rapidfire/application_helper.rb +25 -0
  9. data/app/models/rapidfire/answer.rb +6 -1
  10. data/app/models/rapidfire/attempt.rb +1 -1
  11. data/app/models/rapidfire/question.rb +33 -3
  12. data/app/models/rapidfire/questions/checkbox.rb +1 -1
  13. data/app/models/rapidfire/questions/file.rb +6 -0
  14. data/app/models/rapidfire/questions/information.rb +6 -0
  15. data/app/models/rapidfire/questions/multi_file.rb +6 -0
  16. data/app/models/rapidfire/survey.rb +42 -2
  17. data/app/services/rapidfire/attempt_builder.rb +14 -2
  18. data/app/services/rapidfire/question_form.rb +5 -1
  19. data/app/services/rapidfire/survey_results.rb +38 -4
  20. data/app/views/rapidfire/answers/_checkbox.html.erb +1 -1
  21. data/app/views/rapidfire/answers/_date.html.erb +1 -1
  22. data/app/views/rapidfire/answers/_file.html.erb +5 -0
  23. data/app/views/rapidfire/answers/_information.html.erb +4 -0
  24. data/app/views/rapidfire/answers/_long.html.erb +1 -1
  25. data/app/views/rapidfire/answers/_multifile.html.erb +5 -0
  26. data/app/views/rapidfire/answers/_numeric.html.erb +1 -1
  27. data/app/views/rapidfire/answers/_radio.html.erb +1 -1
  28. data/app/views/rapidfire/answers/_select.html.erb +1 -1
  29. data/app/views/rapidfire/answers/_short.html.erb +1 -1
  30. data/app/views/rapidfire/attempts/_form.html.erb +1 -1
  31. data/app/views/rapidfire/attempts/edit.html.erb +1 -1
  32. data/app/views/rapidfire/attempts/new.html.erb +1 -1
  33. data/app/views/rapidfire/questions/_form.html.erb +1 -1
  34. data/app/views/rapidfire/surveys/_survey.html.erb +6 -0
  35. data/app/views/rapidfire/surveys/index.html.erb +7 -2
  36. data/app/views/rapidfire/surveys/results.html.erb +3 -1
  37. data/db/migrate/20190701274749_add_active_to_surveys.rb +12 -0
  38. data/lib/generators/rapidfire/active_survey_migration_generator.rb +18 -0
  39. data/lib/generators/rapidfire/templates/migrations/add_active_to_survey.rb +5 -0
  40. data/lib/rapidfire/version.rb +1 -1
  41. data/lib/tasks/change_delimiter_to_srsn.rake +1 -1
  42. data/lib/tasks/rapidfire.rake +10 -0
  43. data/spec/dummy/README.rdoc +1 -1
  44. data/spec/dummy/app/assets/config/mainfest.js +2 -0
  45. data/spec/dummy/app/models/application_record.rb +3 -0
  46. data/spec/dummy/app/models/user.rb +2 -0
  47. data/spec/dummy/app/views/layouts/application.html.erb +0 -2
  48. data/spec/dummy/config/application.rb +22 -3
  49. data/spec/dummy/config/environments/test.rb +5 -0
  50. data/spec/dummy/config/storage.yml +7 -0
  51. data/spec/dummy/db/migrate/20170701191422_create_users.rb +15 -0
  52. data/spec/dummy/db/migrate/20230402174122_create_active_storage_tables.active_storage.rb +67 -0
  53. data/spec/dummy/db/schema.rb +53 -17
  54. data/spec/dummy/db/test.sqlite3 +0 -0
  55. data/spec/dummy/log/test.log +76140 -14034
  56. data/spec/dummy/tmp/capybara/capybara-202304042341376066162578.html +29 -0
  57. data/spec/dummy/tmp/capybara/capybara-202304042343302647462912.html +29 -0
  58. data/spec/dummy/tmp/capybara/capybara-202304042343539524195351.html +29 -0
  59. data/spec/dummy/tmp/capybara/capybara-202304042344039569698410.html +29 -0
  60. data/spec/dummy/tmp/capybara/capybara-202304042344107081227684.html +29 -0
  61. data/spec/dummy/tmp/capybara/capybara-202304042346131668826835.html +29 -0
  62. data/spec/dummy/tmp/capybara/capybara-202304042346251478672095.html +29 -0
  63. data/spec/dummy/tmp/capybara/capybara-202304042346382011987550.html +29 -0
  64. data/spec/dummy/tmp/capybara/capybara-20230404234755589239852.html +29 -0
  65. data/spec/dummy/tmp/capybara/capybara-202304042348377947112508.html +29 -0
  66. data/spec/dummy/tmp/capybara/capybara-202304042348502970551073.html +55 -0
  67. data/spec/dummy/tmp/capybara/capybara-202304042351403473706214.html +29 -0
  68. data/spec/dummy/tmp/capybara/capybara-202304042352069122239363.html +29 -0
  69. data/spec/dummy/tmp/capybara/capybara-202304042353148433036065.html +29 -0
  70. data/spec/dummy/tmp/capybara/capybara-202304042353383278368450.html +29 -0
  71. data/spec/dummy/tmp/capybara/capybara-202304042358431743077504.html +20 -0
  72. data/spec/dummy/tmp/capybara/capybara-202304042358433434523512.html +20 -0
  73. data/spec/dummy/tmp/capybara/capybara-202304042358434379121493.html +20 -0
  74. data/spec/dummy/tmp/capybara/capybara-202304042358492996621343.html +20 -0
  75. data/spec/dummy/tmp/storage/2e/vk/2evksypp3ct4p9cjihfxwomru17i +1 -0
  76. data/spec/dummy/tmp/storage/9k/xt/9kxth5brdkw4huy7lciesekum0pt +1 -0
  77. data/spec/dummy/tmp/storage/cu/44/cu4452jrce4gd0ebcqop1d22kwbs +1 -0
  78. data/spec/dummy/tmp/storage/dl/oy/dloy0dbuquwe0f48bhugjca71pbv +1 -0
  79. data/spec/dummy/tmp/storage/h5/vc/h5vcb12f2cviqinrckfmmz4wtsa7 +1 -0
  80. data/spec/dummy/tmp/storage/ht/4x/ht4xma120asy3gd0fpeseddjzb2l +1 -0
  81. data/spec/dummy/tmp/storage/ip/au/ipauutuc5vy678hrwz4jx3rvm0n6 +1 -0
  82. data/spec/dummy/tmp/storage/j1/uy/j1uyrkrosby81sgq1mf59bs7oqee +1 -0
  83. data/spec/dummy/tmp/storage/nj/vv/njvvpx93zptrmlwbwiuxmxyh1jnf +1 -0
  84. data/spec/dummy/tmp/storage/nv/nx/nvnxlyvw3vd8xsq2sa4eazqepgbn +1 -0
  85. data/spec/dummy/tmp/storage/of/b4/ofb41sjj1mp33qs3wsivadhuts3p +1 -0
  86. data/spec/dummy/tmp/storage/og/ee/ogeerywp2y4szmnlrc5fnuya2evl +1 -0
  87. data/spec/dummy/tmp/storage/wz/oc/wzocvk4ahpp7kwc951u7f78nj259 +1 -0
  88. data/spec/dummy/tmp/storage/z3/vx/z3vxuitmnxld08m0qvt9057uyglc +1 -0
  89. data/spec/dummy/tmp/storage-7.0.0-ruby-3.2.0/1b/cx/1bcxhbuf0bwp8uduq76gye1v11al +1 -0
  90. data/spec/dummy/tmp/storage-7.0.0-ruby-3.2.0/40/x5/40x5xe5nmit9ngld2lngzfjp6r6x +1 -0
  91. data/spec/dummy/tmp/storage-7.0.0-ruby-3.2.0/7h/za/7hza4otjknyyo14szs2az8wiu7ai +1 -0
  92. data/spec/dummy/tmp/storage-7.0.0-ruby-3.2.0/ad/ct/adct5ysy5mq6kyptqk5q3fzfpwui +1 -0
  93. data/spec/dummy/tmp/storage-7.0.0-ruby-3.2.0/bl/yo/blyo13wkf0l9igpyq4anaqbomz0h +1 -0
  94. data/spec/dummy/tmp/storage-7.0.0-ruby-3.2.0/cc/g8/ccg8282dt6ixi4yvvwjt4noqa6pj +1 -0
  95. data/spec/dummy/tmp/storage-7.0.0-ruby-3.2.0/d3/gj/d3gjt0qoinigrbao1anp4hmvedjm +1 -0
  96. data/spec/dummy/tmp/storage-7.0.0-ruby-3.2.0/f2/bv/f2bvz6ws3xfrk17dpzhyacx3kys2 +1 -0
  97. data/spec/dummy/tmp/storage-7.0.0-ruby-3.2.0/f8/3z/f83z2f041tfpu39ygi0gu32wai8x +1 -0
  98. data/spec/dummy/tmp/storage-7.0.0-ruby-3.2.0/gt/rc/gtrco13ij0i2vi27t6wm1jhcve5p +1 -0
  99. data/spec/dummy/tmp/storage-7.0.0-ruby-3.2.0/k8/br/k8br0vtpgmpqxrl8mdsceymh3c8d +1 -0
  100. data/spec/dummy/tmp/storage-7.0.0-ruby-3.2.0/mw/le/mwle6olsgsk8h2pxvklj5q0yr9sc +1 -0
  101. data/spec/dummy/tmp/storage-7.0.0-ruby-3.2.0/n7/ja/n7jacvu07s9z9ai7acjq8kovdh02 +1 -0
  102. data/spec/dummy/tmp/storage-7.0.0-ruby-3.2.0/o1/2w/o12whqlkt6rc0yaq3b6fsowmewdp +1 -0
  103. data/spec/dummy/tmp/storage-7.0.0-ruby-3.2.0/o9/2g/o92go6wavds5oht0dso6m1ybvbh4 +1 -0
  104. data/spec/dummy/tmp/storage-7.0.0-ruby-3.2.0/om/7f/om7frlle7xz8pybxbydeq1q20hro +1 -0
  105. data/spec/dummy/tmp/storage-7.0.0-ruby-3.2.0/q6/78/q678f1u8v1nv07dbtm85knmw3b9q +1 -0
  106. data/spec/dummy/tmp/storage-7.0.0-ruby-3.2.0/qq/kc/qqkciwi2vymum1556755n85po1j9 +1 -0
  107. data/spec/dummy/tmp/storage-7.0.0-ruby-3.2.0/r4/wp/r4wpzje2mix0dtl8r2f4akh18fm1 +1 -0
  108. data/spec/dummy/tmp/storage-7.0.0-ruby-3.2.0/v1/h9/v1h9cuuwtwvz8p6fl574qum6k4ig +1 -0
  109. data/spec/dummy/tmp/storage-7.0.0-ruby-3.2.0/vb/mw/vbmwrl014lccj3jo61vojqscfxha +1 -0
  110. data/spec/dummy/tmp/storage-7.0.0-ruby-3.2.0/wn/q4/wnq49hhhxvh4gnc2782lf4zzlz46 +1 -0
  111. data/spec/dummy/tmp/storage-7.0.0-ruby-3.2.0/ya/go/yago1kn4o7p8jfob0cxetrif714s +1 -0
  112. data/spec/factories/questions_factory.rb +6 -0
  113. data/spec/factories/users_factory.rb +5 -0
  114. data/spec/features/rapidfire/answering_questions_spec.rb +47 -7
  115. data/spec/fixtures/files/one.txt +1 -0
  116. data/spec/fixtures/files/two.txt +1 -0
  117. data/spec/models/rapidfire/attempt_spec.rb +5 -1
  118. data/spec/models/rapidfire/questions/file_spec.rb +57 -0
  119. data/spec/models/rapidfire/questions/multi_file_spec.rb +60 -0
  120. data/spec/services/rapidfire/attempt_builder_spec.rb +61 -13
  121. metadata +184 -232
  122. data/spec/dummy/db/development.sqlite3 +0 -0
  123. data/spec/dummy/log/development.log +0 -200
  124. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/-N/-Nnl5LNk36kVPJf_3kuN5xu7Ebj5HCbnrsyxphSIsdg.cache +0 -0
  125. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/-o/-ojJ77Tf5UKdeHBEDmWtQ_3tnTJqQ0nd-YsKamqADUE.cache +0 -1
  126. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/2b/2bErzwvSRmQv4cAljE5MLyihOZ0NcAw3J8cE3Lt0e4Q.cache +0 -0
  127. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/4C/4CJwpaeIKdXtjEAju7_wQgXuYrzr55ARwRJeVKN7CPM.cache +0 -0
  128. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/4U/4UispN4bfPqEzViX3T416Fr-T-7awbayU5fSryvLFNw.cache +0 -0
  129. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/4k/4kH3sikLuE3o4jE_TNDlBNrlF7XAo_qYtBA6ckHGa5I.cache +0 -0
  130. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/7d/7drzegBZRzthT8NYQjAVcg1mCXgXUj5USwB8GQ1o23Y.cache +0 -1
  131. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/80/80TT8hyotZ8-XWzQe7ELHNN8U6Mp2oGKwqa6Ckoksx0.cache +0 -1
  132. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/8F/8FRx5PWf5mlaMlBnq_oPScrqvzB2csCEVlQ-FbB7Jy8.cache +0 -0
  133. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/8M/8MNahq2o0fNDjjgT-erC9ZV3sFYg4ifFZqlLkcifOSA.cache +0 -1
  134. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/8W/8WURt7NXtVdx9vbcRVtNXo2mqrL-0LPzw609oR1ZXnk.cache +0 -0
  135. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/8k/8kFdViWjxSCYCA00vzJCIk-Hl7Dv6xCJ_Ce3jZALweg.cache +0 -1
  136. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/9-/9-6v3_GF1yDfksWqHBJ96NiduUWyrW5R3k6MQzVpork.cache +0 -0
  137. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/94/94L1rKpX0k77vTIGtqElUDP4dpQXrCmvpI9CmQcZ_aM.cache +0 -1
  138. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/9s/9s2S3Z_vncpN-gwuV05kcjhELi_kX-saO8shiQRx8cU.cache +0 -0
  139. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/AS/AS1POBxm-FJcvGXfKUC02RI960YWQRZP6B5bJ9Pc8qU.cache +0 -1
  140. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/AS/Asy0YwmSFpm-OyM4_Lb9v5CTPAePa74fljOfWyS3SJY.cache +0 -0
  141. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/AY/AYSNFEx7wRHtwbVh3cNGid6wCMdfgyk9ocorMLfRqx4.cache +0 -0
  142. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/Bk/BkxzEgJOpM-iCKaxrcsZlyRZeZKYVDlUj0C-sPXVGPc.cache +0 -0
  143. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/CW/CW8uYbA8W5LQ0T8Bo2ygunrwYuaHB0kJJuXlPlGA5F8.cache +0 -1
  144. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/Co/CooYsvCeOgtDx9ZKSzQADfurwS4WGsVpyNXMlWum68U.cache +0 -0
  145. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/DC/DCdg25PhcFibsQItx9ofgOr68CacLQumta_lSKJCoOg.cache +0 -1
  146. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/Db/DbmLC3wtG7ztEvkzmVAubW8vf37XdD0bT3Kh73oed1A.cache +0 -0
  147. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/Db/dBQCcGB2fmK2CTrjrkLGxVmGKqBC2AZAx2C6TUMa1XY.cache +0 -0
  148. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/Dn/Dn7Jw00mRZVDDxhjSg9300HJb_1875nlul_DHMMinn8.cache +0 -1
  149. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/IH/IHV1NrIJaxcdliBIo7Z7i28Nqm-8xd7RplmATbQZysI.cache +0 -0
  150. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/Ie/IemA55SqXkoyW_cD7FDwSk834ZydXI6UJpy7QsD-H5Q.cache +0 -0
  151. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/K7/K7SHc_erMPqr16VuAuVxvKfOUmN9Xf9zCR5Mmr6jOTo.cache +0 -0
  152. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/KG/KGhjc0Py_DB3csmx7Y7NGPUOfnsPXP_KJc94bFEIZls.cache +0 -1
  153. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/Lz/LzA8Mm_F0jmw6BK_4ca5scIcIGc6RjWV54G-BeQv8cA.cache +0 -0
  154. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/MP/MPTz2thdBdQPKUgb5k1oYWT6cmJYgRTEz_NEYDQt7E0.cache +0 -0
  155. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/Mt/MtTjUV8qKCTEH961LJhYQWADgVragV9D9xWWiCmxyNc.cache +0 -1
  156. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/O9/O9WxLI48Zh1ES7ZCQC-cX2C7A_-Wg_c_kUOsIHodXW0.cache +0 -0
  157. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/Qo/QoZwnBtkSf3joyR1_5FKACUOgfoO35xMFOfLJkJqFD8.cache +0 -1
  158. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/R6/R6G-TFFztlxL5XDMIFX62wKkfUfmib6oV93z-xCZWsU.cache +0 -1
  159. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/Ry/Ry0Py6y0kHcEYq6qNWzUVQaMeP_p4kGPbD3ZchhmvEA.cache +0 -1
  160. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/SD/SDy6hVbUInn62jE9aAJObZ8NmVkGE5sF7KxhzNEwjys.cache +0 -0
  161. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/SD/sdxeRQBFEvjbUw-k3jsefKcslmEkm88PryW_XDPfOWU.cache +0 -0
  162. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/SH/SHUtigN8XJz-0yTSrOMb-kFlv8iOSvIKmMU76EwSoY0.cache +0 -0
  163. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/Tg/TgTcVvqf5KTGti25aDSVdPzdEFSzFCA7TIgv36nVcSw.cache +0 -0
  164. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/Tj/TjvztGCZ2bx84O9DtrIqlbV9f36XZWuZRucFAwvdgJI.cache +0 -0
  165. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/Tw/Twx5_JY_0JVEAdweDWUNH8zBfK8PB6OnwROdMaXHv98.cache +0 -1
  166. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/UD/UD9ueo8syy1g__X14lIaWY51JAsI5nkxjvn4iz7-B68.cache +0 -1
  167. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/VY/VYOSVFxELVZ_dWFjIfo96exB1iYypEPPaE0U-NYUk3I.cache +0 -0
  168. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/Vq/VqF69IHPfaZOy6Wd3s10PIQmt2iWbU7UKgi7gGhoY6c.cache +0 -1
  169. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/W3/W3k3ezbkIWPsSAffgGGMKKSe_1CPV2jCUAXtFPSKTjE.cache +0 -0
  170. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/XY/XYnyPDtRIxqi5PSIcR0DKovMSyfgt-vquXm2oF4YcYU.cache +0 -0
  171. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/Xe/Xez_IMQeyfLa4U_cntyZgtqAxc9P-spYMcKOwgwqfUk.cache +0 -1
  172. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/Xp/XpKq_V1bVRTt2Dm9n2LFly2fc7rc63m5n0TkruAIT9U.cache +0 -1
  173. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/YQ/YQ07c7yZvQDkWCDNv-r_m3MczWVJMkpDlY6mItSQvDI.cache +0 -0
  174. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/_D/_Du4UKNyRoKp1L8GangzMxQuHGRXv9UNLRFzUUG-8Mo.cache +0 -0
  175. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/_i/_ioj978qaHpKe71YAPRTMr52bYBz1jBQH_a9jnVNxto.cache +0 -1
  176. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/a9/a9w-3USbjccL8aE_56A0EsenyNCD6btCxgmr4_s-LVk.cache +0 -0
  177. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/c6/c6TDdHnqxfaHueLdYt538jXw_7RBFpECFkp7A4pWUfs.cache +0 -1
  178. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/dH/dH4Xkqb5rV9DHHmRa_ODseSEFnlwS0AXeHgoCYqkkZ8.cache +0 -0
  179. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/dU/dUHj3xc9qlZfXc7VP69mfddx5l1sXwlfejSWXIdb1JQ.cache +0 -1
  180. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/de/derm8VJMOzbaRf2rY8Vz6WSHk5w-XAKJIsAIHU5Ng58.cache +0 -1
  181. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/e6/e6jkUzONoMPGAC7nyZsGla8Zm7wPlhXwijdHIYF-FTo.cache +0 -0
  182. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/fJ/fJ5wsH-IHhi_3Wg-4Yk01_O8Bw8SpcxPh-PaN6n38CQ.cache +0 -0
  183. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/g3/g3XXzOg1WKmExnfECaHxaHbjrF8feoJ60TwJJQzWlhI.cache +0 -0
  184. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/g4/g4tbfWjrt8uCm6WfFre4E1yEp4WC9rV9pFrA_9VHQys.cache +0 -0
  185. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/gm/gmSFGhfFSAm1wrLyyGXOUXMn-kygBbG7Zf3unPKzEWw.cache +0 -1
  186. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/gz/gz6bIRfuHgLuNBVVsocUuzLbEU4gEneTbmvzi27eoho.cache +0 -0
  187. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/hM/hMgVzrZus4Z8I8AXg5NPYgizKLI5WwSbt5NKdK00slk.cache +0 -0
  188. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/iw/iwQwbZENFRwrGzETXtK_2_3aqWyAENDNwJAdJu1RoBg.cache +0 -1
  189. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/kJ/kJSsmIsKQHNWdfJ2rMMpTZQ6DeAipIUyiXdftUlXr4I.cache +0 -0
  190. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/ky/ky_7gNCiNp9E5HHXqszipoMZuSpcxD9ceXe46g_5VzI.cache +0 -1
  191. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/lJ/lJf_GZ6JzbMPq2WIEKNQKFh5vI9T8ylMDcZQMcgj1fg.cache +0 -1
  192. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/lo/lo0mbuMJiW9QksbTzvZ6N6aknuNrk1sJCprfNsMJw50.cache +0 -0
  193. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/m8/m801v81Cvh2CcUpw7286U_9CC2tO0z4XBKhfVx8OabE.cache +0 -1
  194. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/mY/mYUyrqDItAnpMyLO7mNA7gPs93yNLb7Hr66jqh-aJmk.cache +0 -1
  195. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/oT/oT7WJVi5xRK0iTbo-MPPVRF3__YNxLiK-kG2oSzeHgA.cache +0 -1
  196. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/pr/prpHKLWY8kH_ZR0CBQBubKTbYRVzUx-u2RzceRwSedM.cache +0 -0
  197. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/py/py8m2jF8ezxgbkf0QTl2FPU21gpWQgvz96UpLr4JCbQ.cache +0 -1
  198. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/q3/q3AuG3GbIVzhGBdYCriWe8FktR40JLxYfJyauA0-CCs.cache +0 -1
  199. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/q6/q6BYa32YJF11eGVapO4ouNl6gayPIsARgMavlzZmoi0.cache +0 -0
  200. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/q7/q7yl5Q_Rk3hQdNI2dKzooG6EkbWvfGaywsvHDtNBX3E.cache +0 -0
  201. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/rc/rcasFMX-bUWsjC8vmfqpoKL6LDbNyRqjBOBJn6KxQrM.cache +0 -1
  202. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/rh/rh0ehR00zu0AmhmksJoUmSMhi6eKb30JpiSLU1Y7vGY.cache +0 -0
  203. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/t6/t6ve2uEx0ZpKYVPLJkiSm3_3nVj8hVs0ouPs-j1Y-Lw.cache +0 -0
  204. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/tF/tFs-J47Vhauit7rJvH6_RG3NydHacSvI1Wn_BPK8OBs.cache +0 -1
  205. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/uU/uUfexZe40_0TvILVKPsXUS5gjsc4iul3OZCrWoXS0Qo.cache +0 -1
  206. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/vF/vFj_rUSzkEPWTAvaVnIUzkZIbfolIXH2bitACRZYWAU.cache +0 -1
  207. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/vk/vk-e_ORxd49RmmTia4r2ajyVw0p-xcUuz8uz8Nx_LUw.cache +0 -1
  208. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/wa/wab9PO75nglTE-rq2pVPg22CRkZW_yTq_WcZ6BEp8T0.cache +0 -0
  209. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/wd/wdHNDzQjfQYx2VQbObEoz4iNxGhcuum4uypNBmnuNpA.cache +0 -1
  210. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/wu/wuO0z3wuhphrqHOHqZdrZd6lFv2u0_Gq7BkDoc_8cEw.cache +0 -1
  211. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/x7/x7KkTV3ibfIEysLB_ug5bfmnn2VLV_BldukPR3EoPBk.cache +0 -0
  212. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/xg/xge95XbE6Me8MVp8Pnz9FbKOZhvzndxHzh-uOjZV5_s.cache +0 -0
  213. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/xz/Xz-wkd5XTDRNs5mNRhBpx4RSe0LN9ajplnuDcli51jE.cache +0 -1
  214. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/xz/xzFhuo3m7qD5I9Xc85aP9j6kR-iAOB0najl9uu7hdMc.cache +0 -1
  215. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/yn/ynGH6ruy4vPfFCwXOH8rgd3f-UWmo05h37jjH0cii8E.cache +0 -1
  216. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/yw/yw6SDVVxzUeXqN9VX1eCGWTN809mt05p0JnedEBCZ7w.cache +0 -0
  217. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/zg/zg53gL5TWyca4nbWc_d4pFhJ7huiu6zm1BTDcALsP8c.cache +0 -1
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 057dce98ba358c61326f29a6b7a421f0aa50fd11abfc3fbe5ca414dd91bdaee2
4
- data.tar.gz: bf897389f256d72d09e880a5d89c1791553e13a109e91ce4877ad57a4287fb74
3
+ metadata.gz: dabe714dbf4a6938fc95b0f9f598326f9414649515a0be018967c98a8da384f9
4
+ data.tar.gz: 8c801984adc0c4b902ee562e2e6d716a117b820a2ee5f377bfa580cc1f8ca3f6
5
5
  SHA512:
6
- metadata.gz: 8e697ecacc4b2173e61aa88d0160b92a5d82d6180ebdaa446093d29987bb29918f10d64c67b48ff1888b126d769920ede8e67f20e21972b1150704bcda97c226
7
- data.tar.gz: 04c7367d6ee40bf0c75a620403b30b6b78dd94e7cd2743c7f5c8867d52d6dfaee399d58a259a9a47be21a80fb51e600accf794ff9ea8101f3e1a01c7634430b2
6
+ metadata.gz: 6800183f4c4638eb513aa4b4826d5a584bf8b86cbbe99c013f6620594b26f4ce31546504aa5cf5518c4203ec6d54dd57f7d5c6892dc1277993026edcc09efa69
7
+ data.tar.gz: 1bff2e121df60d98f55e992b73429bc2bd252fe1a7cc306b95f240f792c8e9e6c5c9b50b0b56819e3f3c797c701278f5dea01bfffbfa9914ce60449e2f3147f1
data/README.md CHANGED
@@ -1,46 +1,54 @@
1
1
  # Rapidfire
2
- [![Code Climate](https://codeclimate.com/github/code-mancers/rapidfire/badges/gpa.svg)](https://codeclimate.com/github/code-mancers/rapidfire)
3
- [![Build Status](https://travis-ci.org/code-mancers/rapidfire.png?branch=master)](https://travis-ci.org/code-mancers/rapidfire)
4
2
 
5
3
  One stop solution for all survey related requirements! Its tad easy!
6
4
 
7
- This gem supports **rails 4.2.0+**, **rails 5** and **rails 6** with **ruby 2.4** and later.
5
+ This gem supports:
8
6
 
9
- You can see a demo of this gem [here](https://rapidfire.herokuapp.com).
10
- And the source code of demo [here](https://github.com/code-mancers/rapidfire-demo).
7
+ - **rails**: 4.2, 5.0, 5.1, 5.2, 6.0, 6.1 and 7.0
8
+ - **ruby**: 2.4, 2.5, 2.6, 2.7, 3.0, 3.1 and 3.2
9
+
10
+ NOTE: Some combinations won't be supported. Please check CI for the ignored ones.
11
+
12
+ A simple implementaiton of this gem can be found at [https://rapidfire.fly.dev](https://rapidfire.fly.dev).
13
+ And the source code of application is [https://github.com/code-mancers/rapidfire-app](https://github.com/code-mancers/rapidfire-app).
11
14
 
12
15
  ## Installation
13
- Add this line to your application's Gemfile:
16
+
17
+ Add this line to application's Gemfile:
14
18
 
15
19
  ```rb
16
- gem 'rapidfire'
20
+ gem 'rapidfire'
17
21
  ```
18
22
 
19
23
  And then execute:
20
24
 
21
25
  ```shell
22
- $ bundle install
23
- $ bundle exec rake rapidfire:install:migrations
24
- $ bundle exec rake db:migrate
26
+ $ bundle install
27
+ $ bundle exec rake rapidfire:install:migrations
28
+ $ bundle exec rake db:migrate
25
29
  ```
26
30
 
27
- And if you want to customize rapidfire views, you can do
31
+ Rapidfire views can also be customized. This command copies the views into `app/views` directory:
28
32
 
29
- $ bundle exec rails generate rapidfire:views
33
+ ```sh
34
+ $ bundle exec rails generate rapidfire:views
35
+ ```
30
36
 
31
- If you want to customize rapidfire locales (i18n) files, you can do
37
+ Rapidfire locales (i18n) files can also be customized. The command is:
32
38
 
33
- $ bundle exec rails generate rapidfire:locales
39
+ ```sh
40
+ $ bundle exec rails generate rapidfire:locales
41
+ ```
34
42
 
35
43
  ## Usage
36
44
 
37
- Add this line to your routes will and you will be good to go!
45
+ Add this line to `config/routes.rb` file, thats good enough
38
46
 
39
47
  ```rb
40
- mount Rapidfire::Engine => "/rapidfire"
48
+ mount Rapidfire::Engine => "/rapidfire"
41
49
  ```
42
50
 
43
- And point your browser to [http://localhost:3000/rapidfire](http://localhost:3000/rapidfire)
51
+ Please point the browser to [http://localhost:3000/rapidfire](http://localhost:3000/rapidfire)
44
52
 
45
53
  All rapidfire controllers inherit from your `ApplicationController`. So define 2
46
54
  methods `current_user` and `can_administer?` on your `ApplicationController`
@@ -52,19 +60,31 @@ methods `current_user` and `can_administer?` on your `ApplicationController`
52
60
  Typical implementation would be:
53
61
 
54
62
  ```rb
55
- class ApplicationController < ActionController::Base
56
- def current_user
57
- @current_user ||= User.find(session[:user_id])
58
- end
59
-
60
- def can_administer?
61
- current_user.try(:admin?)
62
- end
63
+ class ApplicationController < ActionController::Base
64
+ def current_user
65
+ @current_user ||= User.find(session[:user_id])
66
+ end
67
+
68
+ def can_administer?
69
+ current_user.try(:admin?)
70
+ end
71
+ end
72
+ ```
73
+
74
+ It also will assume that whatever `current_user` returns above will respond to a method called `survey_name`.
75
+
76
+ That method should return the name that is associated with the results. For example:
77
+
78
+ ```rb
79
+ class User
80
+ def survey_name
81
+ "#{last_name}, #{first_name}"
63
82
  end
83
+ end
64
84
  ```
65
85
 
66
- If you are using authentication gems like devise, you get `current_user` for free
67
- and you don't have to define it.
86
+ If the application is using authentication gems like Devise, Devise will automatically provide `current_user`
87
+ helper for free. There is no need to define it
68
88
 
69
89
  ### Override
70
90
 
@@ -80,8 +100,9 @@ end
80
100
  ```
81
101
 
82
102
  ### Routes Information
103
+
83
104
  Once this gem is mounted on, say at 'rapidfire', it generates several routes
84
- You can see them by running `bundle exec rake routes`.
105
+ They can be listed by running `bundle exec rake routes`.
85
106
 
86
107
  1. The `root_path` i.e `localhost:3000/rapidfire` always points to list of
87
108
  surveys {they are called question groups}. Admin can manage surveys, and
@@ -89,11 +110,11 @@ You can see them by running `bundle exec rake routes`.
89
110
  2. Optionally, each survey can by answered by visiting this path:
90
111
 
91
112
  ```
92
- localhost:3000/rapidfire/surveys/<survey-id>/answer_groups/new
113
+ localhost:3000/rapidfire/surveys/<survey-id>/attempts/new
93
114
  ```
94
115
 
95
- You can distribute this url so that survey takers can answer a particular survey
96
- of your interest.
116
+ This url can be distributed so that survey takers can attempt the survey
117
+
97
118
  3. If you have an established application that uses route helpers and/or the
98
119
  `url_for([@model1, @model2])` style, you can include your route helpers in
99
120
  RapidFire by adding `config/initializers/rapidfire.rb` with the
@@ -117,18 +138,21 @@ You can see them by running `bundle exec rake routes`.
117
138
  ```
118
139
 
119
140
  ### Survey Results
120
- A new api is released which helps in seeing results for each survey. The api is:
141
+
142
+ There is an API for fetching the results. This is not efficient, but is provided for the sake
143
+ of quickly aggregating survey results
121
144
 
122
145
  ```
123
- GET /rapidfire/surveys/<survey-id>/results
146
+ GET /rapidfire/surveys/<survey-id>/results
124
147
  ```
125
- This new api supports two formats: `html` and `json`. The `json` format is supported
126
- so that end user can use any javascript based chart solutions and render results
127
- in the format they pleased. An example can be seen [here](https://github.com/code-mancers/rapidfire-demo),
128
- which uses chart.js to display results.
148
+
149
+ This new api supports two formats: `html` and `json`. The `json` format can be used with any
150
+ javascript based chart solutions like Chart.js. An example can be seen
151
+ [here](https://github.com/code-mancers/rapidfire-app).
129
152
 
130
153
  Diving into details of `json` format, all the questions can be categorized into
131
154
  one of the two categories:
155
+
132
156
  1. **aggregatable**: questions like checkboxes, selects, radio buttons fall into
133
157
  this category.
134
158
  2. **non-aggregatable**: questions like long answers, short answers, date, numeric
@@ -140,68 +164,60 @@ output will be like this:
140
164
 
141
165
  ```json
142
166
  [
143
- {
167
+ {
144
168
  "question_type": "Rapidfire::Questions::Radio",
145
169
  "question_text": "Who is author of Waiting for godot?",
146
170
  "results": {
147
- "Sublime": 1,
148
- "Emacs": 1,
149
- "Vim": 1
171
+ "Sublime": 1,
172
+ "Emacs": 1,
173
+ "Vim": 1
150
174
  }
151
- },
152
- {
175
+ },
176
+ {
153
177
  "question_type": "Rapidfire::Questions::Checkbox",
154
178
  "question_text": "Best rock band?",
155
179
  "results": {
156
- "Led Zeppelin": 2
180
+ "Led Zeppelin": 2
157
181
  }
158
- },
159
- {
182
+ },
183
+ {
160
184
  "question_type": "Rapidfire::Questions::Date",
161
185
  "question_text": "When is your birthday?",
162
- "results": [
163
- "04-02-1983",
164
- "01/01/1970"
165
- ]
166
- },
167
- {
186
+ "results": ["04-02-1983", "01/01/1970"]
187
+ },
188
+ {
168
189
  "question_type": "Rapidfire::Questions::Long",
169
190
  "question_text": "If Apple made a android phone what it will be called?",
170
- "results": [
171
- "Idude",
172
- "apdroid"
173
- ]
174
- },
175
- {
191
+ "results": ["Idude", "apdroid"]
192
+ },
193
+ {
176
194
  "question_type": "Rapidfire::Questions::Numeric",
177
195
  "question_text": "Answer of life, universe and everything?",
178
- "results": [
179
- "42",
180
- "0"
181
- ]
182
- },
183
- {
196
+ "results": ["42", "0"]
197
+ },
198
+ {
184
199
  "question_type": "Rapidfire::Questions::Select",
185
200
  "question_text": "Places you want to visit after death",
186
201
  "results": {
187
- "Iran": 2
202
+ "Iran": 2
188
203
  }
189
- }
204
+ }
190
205
  ]
191
206
  ```
192
207
 
193
208
  ## How it works
194
- This gem gives you access to create questions in a groups, something similar to
195
- survey. Once you have created a group and add questions to it, you can pass
196
- around the form url where others can answer your questions.
209
+
210
+ This gem gives on the fly access to create questions under a survey. Once the survey is
211
+ created, questions can be added to the survey. Every survey will have a url which can
212
+ be can passed around to others to take the survey.
197
213
 
198
214
  The typical flow about how to use this gem is:
199
215
 
200
- 1. Create a question group by giving it a name.
201
- 2. Once group is created, you can click on the group which takes you to another
202
- page where you can manage questions.
203
- 3. Create a question by clicking on add new, and you will be provided by these
204
- options: Each question will have a type
216
+ 1. Create a survey by giving it a name.
217
+ 2. Once the survey is created, start adding questions to the survey
218
+ 3. Create a question by clicking on add new, and there will be several options
219
+ Each question will have a type
220
+
205
221
  - **Checkbox** Create a question which contains multiple checkboxes with the
206
222
  options that you provide in `answer options` field. Note that each option
207
223
  should be on a separate line.
@@ -211,8 +227,11 @@ The typical flow about how to use this gem is:
211
227
  - **Radio** It renders set of radio buttons by taking answer options.
212
228
  - **Select** It renders a dropdown by taking answer options.
213
229
  - **Short** It takes a string as an answer. Short answer.
230
+ - **File** It renders a file input which can take only 1 file.
231
+ - **MultiFile** It renders a file input which can take multile files.
232
+
233
+ 4. Once the type is filled, optionally other details can be filled:
214
234
 
215
- 4. Once the type is filled, you can optionally fill other details like
216
235
  - **Question text** What is the question?
217
236
  - **Answer options** Give options separated by newline for questions of type
218
237
  checkbox, radio buttons or select.
@@ -222,21 +241,29 @@ The typical flow about how to use this gem is:
222
241
  - **greater than and less than** Applicable for numeric question where answer
223
242
  is validated with these values.
224
243
 
225
- 5. Once the questions are populated, you can return to root_path ie by clicking
226
- `Surveys` and share distribute answer url so that others can answer
227
- the questions populated.
228
- 6. Note that answers fail to persist of the criteria that you have provided while
229
- creating questions fail.
230
-
244
+ 5. Once the questions are populated, a url will be created which can be shared
245
+ 6. Note that answers fail to persist if the criteria provided while creating the
246
+ questions fail.
231
247
 
232
248
  ## Notes on upgrading
233
249
 
250
+ ##### Adding multitenancy support
251
+
252
+ ```shell
253
+ $ rake rapidfire:upgrade:migrations:multitenancy
254
+ ```
255
+
234
256
  ##### Upgrading from 2.1.0 to 3.0.0
235
257
 
236
- If you are upgrading you need to rename your `rapidfire_question_groups` to `rapidfire_surveys` and `rapidfire_answer_groups` to `rapidfire_attempts`. Run the given task to do that for you.
258
+ Some table names have changed:
259
+
260
+ - `rapidfire_question_groups` to `rapidfire_surveys`, and
261
+ - `rapidfire_answer_groups` to `rapidfire_attempts`.
262
+
263
+ Run this rake task to do this change automatically
237
264
 
238
265
  ```shell
239
- $ rake rapidfire:upgrade:migrations:from210to300
266
+ $ rake rapidfire:upgrade:migrations:from210to300
240
267
  ```
241
268
 
242
269
  ##### Upgrading from 1.2.0 to 2.0.0
@@ -253,33 +280,30 @@ to make existing questions or stored answers to use new delimiter.
253
280
  NOTE: Please take database backup before running this rake task.
254
281
 
255
282
  ```rb
256
- bundle exec rake rapidfire:change_delimiter_from_comma_to_srsn
257
- bundle exec rake rapidfire:change_delimiter_from_comma_to_srsn
283
+ bundle exec rake rapidfire:change_delimiter_from_comma_to_srsn
284
+ bundle exec rake rapidfire:change_delimiter_from_comma_to_srsn
258
285
  ```
259
286
 
260
-
261
- If you dont want to make this change rightaway, and would like to use comma
287
+ If this change is not feasible rightaway, and the application needs to use comma
262
288
  as delimiter, then please use this initializer, but be warned that in future
263
289
  delimiter will be hardcoded to `\r\n`:
264
290
 
265
-
266
291
  ```rb
267
- # /<path-to-app>/config/initializers/rapidfire.rb
292
+ # /<path-to-app>/config/initializers/rapidfire.rb
268
293
 
269
- Rapidfire.config do |config|
270
- config.answers_delimiter = ','
271
- end
294
+ Rapidfire.config do |config|
295
+ config.answers_delimiter = ','
296
+ end
272
297
  ```
273
298
 
274
-
275
299
  ## TODO
300
+
276
301
  1. Add ability to sort questions, so that order is preserved.
277
- 2. Add multi tenant support.
278
302
 
279
303
  ## Contributing
280
304
 
281
305
  1. Fork it
282
- 2. Create your feature branch (`git checkout -b my-new-feature`)
283
- 3. Commit your changes (`git commit -am 'Add some feature'`)
306
+ 2. Create a feature branch (`git checkout -b my-new-feature`)
307
+ 3. Commit all the changes (`git commit -am 'Add some feature'`)
284
308
  4. Push to the branch (`git push origin my-new-feature`)
285
309
  5. Create new Pull Request
@@ -0,0 +1,3 @@
1
+ //= link_tree ../images
2
+ //= link_directory ../javascripts .js
3
+ //= link_directory ../stylesheets .css
@@ -14,8 +14,12 @@ module Rapidfire
14
14
 
15
15
  # Override prefixes to consider the scoped.
16
16
  # for method current_user
17
- def scoped
18
- :user
17
+ def rapidfire_scoped
18
+ if !defined?(super)
19
+ :user
20
+ else
21
+ super
22
+ end
19
23
  end
20
24
  end
21
25
  end
@@ -42,7 +42,7 @@ module Rapidfire
42
42
 
43
43
  def attempt_params
44
44
  answer_params = { params: (params[:attempt] || {}) }
45
- answer_params.merge(user: current_user, survey: @survey, attempt_id: params[:id])
45
+ answer_params.merge(user: rapidfire_current_scoped, survey: @survey, attempt_id: params[:id])
46
46
  end
47
47
 
48
48
  def attempt_params_for_find
@@ -68,7 +68,7 @@ module Rapidfire
68
68
  end
69
69
 
70
70
  def rapidfire_current_scoped
71
- send 'current_'+scoped.to_s
71
+ send 'current_' + rapidfire_scoped.to_s
72
72
  end
73
73
  end
74
74
  end
@@ -55,7 +55,7 @@ module Rapidfire
55
55
  end
56
56
 
57
57
  def find_survey!
58
- @survey = Survey.find(params[:survey_id])
58
+ @survey = Rapidfire::Survey.find(params[:survey_id])
59
59
  end
60
60
 
61
61
  def find_question!
@@ -3,19 +3,30 @@ module Rapidfire
3
3
  before_action :authenticate_administrator!, except: :index
4
4
 
5
5
  def index
6
- @surveys = if defined?(Kaminari)
7
- Survey.page(params[:page])
8
- else
9
- Survey.all
10
- end
6
+ @surveys = Rapidfire::Survey.all
7
+ @surveys = @surveys.page(params[:page]) if defined?(Kaminari)
8
+ @surveys
11
9
  end
12
10
 
13
11
  def new
14
- @survey = Survey.new
12
+ @survey = Rapidfire::Survey.new
15
13
  end
16
14
 
17
15
  def create
18
- @survey = Survey.new(survey_params)
16
+ source_survey = nil
17
+ if params[:copy_survey_id]
18
+ source_survey = Rapidfire::Survey.find(params[:copy_survey_id])
19
+ params[:survey] = source_survey.attributes.except(*%w(created_at updated_at id))
20
+ params[:survey][:name] = "Copy of #{params[:survey][:name]}"
21
+ end
22
+ @survey = Rapidfire::Survey.new(survey_params)
23
+
24
+ if source_survey
25
+ source_survey.questions.each do |q|
26
+ @survey.questions << q.dup
27
+ end
28
+ end
29
+
19
30
  if @survey.save
20
31
  respond_to do |format|
21
32
  format.html { redirect_to surveys_path }
@@ -30,11 +41,11 @@ module Rapidfire
30
41
  end
31
42
 
32
43
  def edit
33
- @survey = Survey.find(params[:id])
44
+ @survey = Rapidfire::Survey.find(params[:id])
34
45
  end
35
46
 
36
47
  def update
37
- @survey = Survey.find(params[:id])
48
+ @survey = Rapidfire::Survey.find(params[:id])
38
49
  if @survey.update(survey_params)
39
50
  respond_to do |format|
40
51
  format.html { redirect_to surveys_path }
@@ -49,7 +60,7 @@ module Rapidfire
49
60
  end
50
61
 
51
62
  def destroy
52
- @survey = Survey.find(params[:id])
63
+ @survey = Rapidfire::Survey.find(params[:id])
53
64
  @survey.destroy
54
65
 
55
66
  respond_to do |format|
@@ -59,21 +70,27 @@ module Rapidfire
59
70
  end
60
71
 
61
72
  def results
62
- @survey = Survey.find(params[:id])
73
+ params[:filter] ||= {}
74
+ @survey = Rapidfire::Survey.find(params[:id])
63
75
  @survey_results =
64
- SurveyResults.new(survey: @survey).extract
76
+ SurveyResults.new(survey: @survey).extract(filter_params)
65
77
 
66
78
  respond_to do |format|
67
79
  format.json { render json: @survey_results, root: false }
68
80
  format.html
69
81
  format.js
82
+ format.csv { send_data(@survey.results_to_csv(filter_params)) }
70
83
  end
71
84
  end
72
85
 
73
86
  private
74
87
 
75
88
  def survey_params
76
- params.require(:survey).permit(:name, :introduction, :after_survey_content)
89
+ params.require(:survey).permit(:name, :introduction, :after_survey_content, :active)
90
+ end
91
+
92
+ def filter_params
93
+ params[:filter].permit({ question_ids: [], options: []})
77
94
  end
78
95
  end
79
96
  end
@@ -11,5 +11,30 @@ module Rapidfire
11
11
  answers.include?(option)
12
12
  end
13
13
 
14
+ def filter_link(question_id, option)
15
+ question_id = question_id.to_s
16
+ option = option.to_s
17
+
18
+ this_filter = {
19
+ question_ids: (params.dig(:filter, :question_ids) || []).map(&:to_s),
20
+ options: (params.dig(:filter, :options) || []).map(&:to_s)
21
+ }
22
+
23
+ if this_filter[:question_ids].include?(question_id) && this_filter[:options].include?(option)
24
+ question_index = this_filter[:question_ids].index(question_id)
25
+ this_filter[:question_ids].delete_at(question_index) if question_index
26
+
27
+ option_index = this_filter[:options].index(option)
28
+ this_filter[:options].delete_at(option_index) if option_index
29
+
30
+ action_description = "Remove from"
31
+ else
32
+ this_filter[:question_ids] << question_id
33
+ this_filter[:options] << option
34
+ action_description = "Add to"
35
+ end
36
+
37
+ link_to "#{action_description} Filter", filter: this_filter
38
+ end
14
39
  end
15
40
  end
@@ -1,11 +1,16 @@
1
1
  module Rapidfire
2
- class Answer < ActiveRecord::Base
2
+ class Answer < ApplicationRecord
3
3
  belongs_to :question
4
4
  belongs_to :attempt, inverse_of: :answers
5
5
 
6
6
  validates :question, :attempt, presence: true
7
7
  validate :verify_answer_text
8
8
 
9
+ if "#{Rails::VERSION::MAJOR}.#{Rails::VERSION::MINOR}" >= "5.2"
10
+ has_one_attached :file
11
+ has_many_attached :files
12
+ end
13
+
9
14
  private
10
15
 
11
16
  def verify_answer_text
@@ -1,5 +1,5 @@
1
1
  module Rapidfire
2
- class Attempt < ActiveRecord::Base
2
+ class Attempt < ApplicationRecord
3
3
  belongs_to :survey
4
4
  has_many :answers, inverse_of: :attempt, autosave: true
5
5
 
@@ -1,11 +1,12 @@
1
1
  module Rapidfire
2
- class Question < ActiveRecord::Base
2
+ class Question < ApplicationRecord
3
3
  belongs_to :survey, :inverse_of => :questions
4
4
  has_many :answers
5
5
 
6
6
  default_scope { order(:position) }
7
7
 
8
8
  validates :survey, :question_text, :presence => true
9
+ validate :type_can_change
9
10
  serialize :validation_rules
10
11
 
11
12
  def self.inherited(child)
@@ -19,14 +20,37 @@ module Rapidfire
19
20
  end
20
21
 
21
22
  def rules
22
- validation_rules || {}
23
+ validation_rules.present? ? validation_rules.symbolize_keys : {}
24
+ end
25
+
26
+ def validation_rules=(val)
27
+ super(val.stringify_keys)
23
28
  end
24
29
 
25
30
  # answer will delegate its validation to question, and question
26
31
  # will inturn add validations on answer on the fly!
27
32
  def validate_answer(answer)
28
33
  if rules[:presence] == "1"
29
- answer.validates_presence_of :answer_text
34
+ case self
35
+ when Rapidfire::Questions::File
36
+ if Rails::VERSION::MAJOR >= 6
37
+ answer.validates_presence_of :file
38
+ else
39
+ if !answer.file.attached?
40
+ answer.errors.add(:file, :blank)
41
+ end
42
+ end
43
+ when Rapidfire::Questions::MultiFile
44
+ if Rails::VERSION::MAJOR >= 6
45
+ answer.validates_presence_of :files
46
+ else
47
+ if !answer.files.attached?
48
+ answer.errors.add(:files, :blank)
49
+ end
50
+ end
51
+ else
52
+ answer.validates_presence_of :answer_text
53
+ end
30
54
  end
31
55
 
32
56
  if rules[:minimum].present? || rules[:maximum].present?
@@ -36,5 +60,11 @@ module Rapidfire
36
60
  answer.validates_length_of :answer_text, min_max
37
61
  end
38
62
  end
63
+
64
+ def type_can_change
65
+ if type_changed? && answers.any?
66
+ errors.add(:type, "cannot change after answers have been added")
67
+ end
68
+ end
39
69
  end
40
70
  end
@@ -14,7 +14,7 @@ module Rapidfire
14
14
  super(answer)
15
15
 
16
16
  if rules[:presence] == "1" || answer.answer_text.present?
17
- answer.answer_text.split(Rapidfire.answers_delimiter).each do |value|
17
+ answer.answer_text.to_s.split(Rapidfire.answers_delimiter).each do |value|
18
18
  answer.errors.add(:answer_text, :invalid) unless options.include?(value)
19
19
  end
20
20
  end
@@ -0,0 +1,6 @@
1
+ module Rapidfire
2
+ module Questions
3
+ class File < Rapidfire::Question
4
+ end
5
+ end
6
+ end
@@ -0,0 +1,6 @@
1
+ module Rapidfire
2
+ module Questions
3
+ class Information < Rapidfire::Question
4
+ end
5
+ end
6
+ end
@@ -0,0 +1,6 @@
1
+ module Rapidfire
2
+ module Questions
3
+ class MultiFile < Rapidfire::Question
4
+ end
5
+ end
6
+ end