rapidfire 4.0.0 → 8.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +120 -96
- data/app/assets/config/manifest.js +3 -0
- data/app/controllers/rapidfire/application_controller.rb +6 -2
- data/app/controllers/rapidfire/attempts_controller.rb +2 -2
- data/app/controllers/rapidfire/questions_controller.rb +1 -1
- data/app/controllers/rapidfire/surveys_controller.rb +30 -13
- data/app/helpers/rapidfire/application_helper.rb +25 -0
- data/app/models/rapidfire/answer.rb +6 -1
- data/app/models/rapidfire/attempt.rb +1 -1
- data/app/models/rapidfire/question.rb +34 -4
- data/app/models/rapidfire/questions/checkbox.rb +1 -1
- data/app/models/rapidfire/questions/file.rb +6 -0
- data/app/models/rapidfire/questions/information.rb +6 -0
- data/app/models/rapidfire/questions/multi_file.rb +6 -0
- data/app/models/rapidfire/survey.rb +42 -2
- data/app/services/rapidfire/attempt_builder.rb +14 -1
- data/app/services/rapidfire/question_form.rb +5 -1
- data/app/services/rapidfire/survey_results.rb +38 -4
- data/app/views/rapidfire/answers/_checkbox.html.erb +1 -1
- data/app/views/rapidfire/answers/_date.html.erb +1 -1
- data/app/views/rapidfire/answers/_file.html.erb +5 -0
- data/app/views/rapidfire/answers/_information.html.erb +4 -0
- data/app/views/rapidfire/answers/_long.html.erb +1 -1
- data/app/views/rapidfire/answers/_multifile.html.erb +5 -0
- data/app/views/rapidfire/answers/_numeric.html.erb +1 -1
- data/app/views/rapidfire/answers/_radio.html.erb +1 -1
- data/app/views/rapidfire/answers/_select.html.erb +1 -1
- data/app/views/rapidfire/answers/_short.html.erb +1 -1
- data/app/views/rapidfire/attempts/_form.html.erb +9 -1
- data/app/views/rapidfire/attempts/edit.html.erb +1 -1
- data/app/views/rapidfire/attempts/new.html.erb +1 -1
- data/app/views/rapidfire/questions/_form.html.erb +1 -1
- data/app/views/rapidfire/surveys/_survey.html.erb +6 -0
- data/app/views/rapidfire/surveys/index.html.erb +7 -2
- data/app/views/rapidfire/surveys/results.html.erb +3 -1
- data/db/migrate/20190701274749_add_active_to_surveys.rb +12 -0
- data/lib/generators/rapidfire/active_survey_migration_generator.rb +18 -0
- data/lib/generators/rapidfire/templates/migrations/add_active_to_survey.rb +5 -0
- data/lib/rapidfire/version.rb +1 -1
- data/lib/tasks/change_delimiter_to_srsn.rake +1 -1
- data/lib/tasks/rapidfire.rake +10 -0
- data/spec/controllers/rapidfire/attempts_controller_spec.rb +1 -1
- data/spec/dummy/README.rdoc +1 -1
- data/spec/dummy/app/assets/config/mainfest.js +2 -0
- data/spec/dummy/app/models/application_record.rb +3 -0
- data/spec/dummy/app/models/user.rb +2 -0
- data/spec/dummy/app/views/layouts/application.html.erb +0 -2
- data/spec/dummy/config/application.rb +22 -3
- data/spec/dummy/config/environments/development.rb +1 -1
- data/spec/dummy/config/environments/test.rb +5 -0
- data/spec/dummy/config/storage.yml +7 -0
- data/spec/dummy/db/development.sqlite3 +0 -0
- data/spec/dummy/db/migrate/20170701191422_create_users.rb +15 -0
- data/spec/dummy/db/migrate/20230402174122_create_active_storage_tables.active_storage.rb +67 -0
- data/spec/dummy/db/schema.rb +51 -17
- data/spec/dummy/db/test.sqlite3 +0 -0
- data/spec/dummy/log/development.log +90 -200
- data/spec/dummy/log/test.log +12744 -14006
- data/spec/dummy/tmp/storage--ruby-3.3.5/81/2n/812ne4iy4c40lvvdigsg8z02b1v1 +1 -0
- data/spec/dummy/tmp/storage--ruby-3.3.5/85/bs/85bsmaecej0491dey4t9jpci9yw3 +1 -0
- data/spec/dummy/tmp/storage--ruby-3.3.5/8y/7b/8y7bhqwxh5cad8xau7nfhtukxcsc +1 -0
- data/spec/dummy/tmp/storage--ruby-3.3.5/93/z6/93z6nje4f921vgdwa3lkuf49xocr +1 -0
- data/spec/dummy/tmp/storage--ruby-3.3.5/at/qk/atqksrev4s0ic4srii57aspu4o6z +1 -0
- data/spec/dummy/tmp/storage--ruby-3.3.5/bi/j3/bij3puzjsfm39colnpqstpu6ggv7 +1 -0
- data/spec/dummy/tmp/storage--ruby-3.3.5/cx/4p/cx4pp9ugdv2xndwll28mo8jhjgig +1 -0
- data/spec/dummy/tmp/storage--ruby-3.3.5/gv/9c/gv9cand9rqcew9sceoirbfm9l2bl +1 -0
- data/spec/dummy/tmp/storage--ruby-3.3.5/m2/ce/m2cehdwpmdl0s5vgylxc1tcbxlr2 +1 -0
- data/spec/dummy/tmp/storage--ruby-3.3.5/md/rj/mdrjgxirkdtyfijfwdxn37dswspm +1 -0
- data/spec/dummy/tmp/storage--ruby-3.3.5/xv/oi/xvoijswvk9a0blrua7x5yl94a6qw +1 -0
- data/spec/dummy/tmp/storage--ruby-3.3.5/z6/cw/z6cw41euxe15z3ao5wkypp0y9liw +1 -0
- data/spec/factories/answers_factory.rb +4 -4
- data/spec/factories/attempts_factory.rb +2 -2
- data/spec/factories/questions_factory.rb +13 -7
- data/spec/factories/surveys_factory.rb +3 -3
- data/spec/factories/users_factory.rb +5 -0
- data/spec/features/rapidfire/answering_questions_spec.rb +66 -9
- data/spec/features/rapidfire/editing_answers_spec.rb +6 -6
- data/spec/features/rapidfire/managing_questions_spec.rb +3 -3
- data/spec/features/rapidfire/managing_surveys_spec.rb +18 -3
- data/spec/fixtures/files/one.txt +1 -0
- data/spec/fixtures/files/two.txt +1 -0
- data/spec/models/rapidfire/answer_spec.rb +2 -2
- data/spec/models/rapidfire/attempt_spec.rb +5 -1
- data/spec/models/rapidfire/question_spec.rb +3 -3
- data/spec/models/rapidfire/questions/checkbox_spec.rb +3 -3
- data/spec/models/rapidfire/questions/date_spec.rb +2 -2
- data/spec/models/rapidfire/questions/file_spec.rb +57 -0
- data/spec/models/rapidfire/questions/multi_file_spec.rb +60 -0
- data/spec/models/rapidfire/questions/numeric_spec.rb +2 -2
- data/spec/models/rapidfire/questions/select_spec.rb +3 -3
- data/spec/models/rapidfire/survey_spec.rb +1 -1
- data/spec/serializers/rapidfire/question_result_serializer_spec.rb +1 -1
- data/spec/services/rapidfire/attempt_builder_spec.rb +64 -16
- data/spec/services/rapidfire/question_form_spec.rb +3 -3
- data/spec/services/rapidfire/survey_results_spec.rb +1 -1
- data/spec/spec_helper.rb +1 -1
- data/spec/support/rapidfire/answer_spec_helper.rb +12 -12
- data/spec/support/rapidfire/question_spec_helper.rb +7 -7
- data/spec/tasks/change_delimiter_from_comma_to_srsn_spec.rb +8 -8
- metadata +106 -240
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/-N/-Nnl5LNk36kVPJf_3kuN5xu7Ebj5HCbnrsyxphSIsdg.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/-o/-ojJ77Tf5UKdeHBEDmWtQ_3tnTJqQ0nd-YsKamqADUE.cache +0 -1
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/2b/2bErzwvSRmQv4cAljE5MLyihOZ0NcAw3J8cE3Lt0e4Q.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/4C/4CJwpaeIKdXtjEAju7_wQgXuYrzr55ARwRJeVKN7CPM.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/4U/4UispN4bfPqEzViX3T416Fr-T-7awbayU5fSryvLFNw.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/4k/4kH3sikLuE3o4jE_TNDlBNrlF7XAo_qYtBA6ckHGa5I.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/7d/7drzegBZRzthT8NYQjAVcg1mCXgXUj5USwB8GQ1o23Y.cache +0 -1
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/80/80TT8hyotZ8-XWzQe7ELHNN8U6Mp2oGKwqa6Ckoksx0.cache +0 -1
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/8F/8FRx5PWf5mlaMlBnq_oPScrqvzB2csCEVlQ-FbB7Jy8.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/8M/8MNahq2o0fNDjjgT-erC9ZV3sFYg4ifFZqlLkcifOSA.cache +0 -1
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/8W/8WURt7NXtVdx9vbcRVtNXo2mqrL-0LPzw609oR1ZXnk.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/8k/8kFdViWjxSCYCA00vzJCIk-Hl7Dv6xCJ_Ce3jZALweg.cache +0 -1
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/9-/9-6v3_GF1yDfksWqHBJ96NiduUWyrW5R3k6MQzVpork.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/94/94L1rKpX0k77vTIGtqElUDP4dpQXrCmvpI9CmQcZ_aM.cache +0 -1
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/9s/9s2S3Z_vncpN-gwuV05kcjhELi_kX-saO8shiQRx8cU.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/AS/AS1POBxm-FJcvGXfKUC02RI960YWQRZP6B5bJ9Pc8qU.cache +0 -1
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/AS/Asy0YwmSFpm-OyM4_Lb9v5CTPAePa74fljOfWyS3SJY.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/AY/AYSNFEx7wRHtwbVh3cNGid6wCMdfgyk9ocorMLfRqx4.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/Bk/BkxzEgJOpM-iCKaxrcsZlyRZeZKYVDlUj0C-sPXVGPc.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/CW/CW8uYbA8W5LQ0T8Bo2ygunrwYuaHB0kJJuXlPlGA5F8.cache +0 -1
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/Co/CooYsvCeOgtDx9ZKSzQADfurwS4WGsVpyNXMlWum68U.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/DC/DCdg25PhcFibsQItx9ofgOr68CacLQumta_lSKJCoOg.cache +0 -1
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/Db/DbmLC3wtG7ztEvkzmVAubW8vf37XdD0bT3Kh73oed1A.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/Db/dBQCcGB2fmK2CTrjrkLGxVmGKqBC2AZAx2C6TUMa1XY.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/Dn/Dn7Jw00mRZVDDxhjSg9300HJb_1875nlul_DHMMinn8.cache +0 -1
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/IH/IHV1NrIJaxcdliBIo7Z7i28Nqm-8xd7RplmATbQZysI.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/Ie/IemA55SqXkoyW_cD7FDwSk834ZydXI6UJpy7QsD-H5Q.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/K7/K7SHc_erMPqr16VuAuVxvKfOUmN9Xf9zCR5Mmr6jOTo.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/KG/KGhjc0Py_DB3csmx7Y7NGPUOfnsPXP_KJc94bFEIZls.cache +0 -1
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/Lz/LzA8Mm_F0jmw6BK_4ca5scIcIGc6RjWV54G-BeQv8cA.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/MP/MPTz2thdBdQPKUgb5k1oYWT6cmJYgRTEz_NEYDQt7E0.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/Mt/MtTjUV8qKCTEH961LJhYQWADgVragV9D9xWWiCmxyNc.cache +0 -1
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/O9/O9WxLI48Zh1ES7ZCQC-cX2C7A_-Wg_c_kUOsIHodXW0.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/Qo/QoZwnBtkSf3joyR1_5FKACUOgfoO35xMFOfLJkJqFD8.cache +0 -1
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/R6/R6G-TFFztlxL5XDMIFX62wKkfUfmib6oV93z-xCZWsU.cache +0 -1
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/Ry/Ry0Py6y0kHcEYq6qNWzUVQaMeP_p4kGPbD3ZchhmvEA.cache +0 -1
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/SD/SDy6hVbUInn62jE9aAJObZ8NmVkGE5sF7KxhzNEwjys.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/SD/sdxeRQBFEvjbUw-k3jsefKcslmEkm88PryW_XDPfOWU.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/SH/SHUtigN8XJz-0yTSrOMb-kFlv8iOSvIKmMU76EwSoY0.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/Tg/TgTcVvqf5KTGti25aDSVdPzdEFSzFCA7TIgv36nVcSw.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/Tj/TjvztGCZ2bx84O9DtrIqlbV9f36XZWuZRucFAwvdgJI.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/Tw/Twx5_JY_0JVEAdweDWUNH8zBfK8PB6OnwROdMaXHv98.cache +0 -1
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/UD/UD9ueo8syy1g__X14lIaWY51JAsI5nkxjvn4iz7-B68.cache +0 -1
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/VY/VYOSVFxELVZ_dWFjIfo96exB1iYypEPPaE0U-NYUk3I.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/Vq/VqF69IHPfaZOy6Wd3s10PIQmt2iWbU7UKgi7gGhoY6c.cache +0 -1
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/W3/W3k3ezbkIWPsSAffgGGMKKSe_1CPV2jCUAXtFPSKTjE.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/XY/XYnyPDtRIxqi5PSIcR0DKovMSyfgt-vquXm2oF4YcYU.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/Xe/Xez_IMQeyfLa4U_cntyZgtqAxc9P-spYMcKOwgwqfUk.cache +0 -1
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/Xp/XpKq_V1bVRTt2Dm9n2LFly2fc7rc63m5n0TkruAIT9U.cache +0 -1
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/YQ/YQ07c7yZvQDkWCDNv-r_m3MczWVJMkpDlY6mItSQvDI.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/_D/_Du4UKNyRoKp1L8GangzMxQuHGRXv9UNLRFzUUG-8Mo.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/_i/_ioj978qaHpKe71YAPRTMr52bYBz1jBQH_a9jnVNxto.cache +0 -1
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/a9/a9w-3USbjccL8aE_56A0EsenyNCD6btCxgmr4_s-LVk.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/c6/c6TDdHnqxfaHueLdYt538jXw_7RBFpECFkp7A4pWUfs.cache +0 -1
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/dH/dH4Xkqb5rV9DHHmRa_ODseSEFnlwS0AXeHgoCYqkkZ8.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/dU/dUHj3xc9qlZfXc7VP69mfddx5l1sXwlfejSWXIdb1JQ.cache +0 -1
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/de/derm8VJMOzbaRf2rY8Vz6WSHk5w-XAKJIsAIHU5Ng58.cache +0 -1
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/e6/e6jkUzONoMPGAC7nyZsGla8Zm7wPlhXwijdHIYF-FTo.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/fJ/fJ5wsH-IHhi_3Wg-4Yk01_O8Bw8SpcxPh-PaN6n38CQ.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/g3/g3XXzOg1WKmExnfECaHxaHbjrF8feoJ60TwJJQzWlhI.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/g4/g4tbfWjrt8uCm6WfFre4E1yEp4WC9rV9pFrA_9VHQys.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/gm/gmSFGhfFSAm1wrLyyGXOUXMn-kygBbG7Zf3unPKzEWw.cache +0 -1
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/gz/gz6bIRfuHgLuNBVVsocUuzLbEU4gEneTbmvzi27eoho.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/hM/hMgVzrZus4Z8I8AXg5NPYgizKLI5WwSbt5NKdK00slk.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/iw/iwQwbZENFRwrGzETXtK_2_3aqWyAENDNwJAdJu1RoBg.cache +0 -1
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/kJ/kJSsmIsKQHNWdfJ2rMMpTZQ6DeAipIUyiXdftUlXr4I.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/ky/ky_7gNCiNp9E5HHXqszipoMZuSpcxD9ceXe46g_5VzI.cache +0 -1
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/lJ/lJf_GZ6JzbMPq2WIEKNQKFh5vI9T8ylMDcZQMcgj1fg.cache +0 -1
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/lo/lo0mbuMJiW9QksbTzvZ6N6aknuNrk1sJCprfNsMJw50.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/m8/m801v81Cvh2CcUpw7286U_9CC2tO0z4XBKhfVx8OabE.cache +0 -1
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/mY/mYUyrqDItAnpMyLO7mNA7gPs93yNLb7Hr66jqh-aJmk.cache +0 -1
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/oT/oT7WJVi5xRK0iTbo-MPPVRF3__YNxLiK-kG2oSzeHgA.cache +0 -1
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/pr/prpHKLWY8kH_ZR0CBQBubKTbYRVzUx-u2RzceRwSedM.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/py/py8m2jF8ezxgbkf0QTl2FPU21gpWQgvz96UpLr4JCbQ.cache +0 -1
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/q3/q3AuG3GbIVzhGBdYCriWe8FktR40JLxYfJyauA0-CCs.cache +0 -1
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/q6/q6BYa32YJF11eGVapO4ouNl6gayPIsARgMavlzZmoi0.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/q7/q7yl5Q_Rk3hQdNI2dKzooG6EkbWvfGaywsvHDtNBX3E.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/rc/rcasFMX-bUWsjC8vmfqpoKL6LDbNyRqjBOBJn6KxQrM.cache +0 -1
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/rh/rh0ehR00zu0AmhmksJoUmSMhi6eKb30JpiSLU1Y7vGY.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/t6/t6ve2uEx0ZpKYVPLJkiSm3_3nVj8hVs0ouPs-j1Y-Lw.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/tF/tFs-J47Vhauit7rJvH6_RG3NydHacSvI1Wn_BPK8OBs.cache +0 -1
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/uU/uUfexZe40_0TvILVKPsXUS5gjsc4iul3OZCrWoXS0Qo.cache +0 -1
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/vF/vFj_rUSzkEPWTAvaVnIUzkZIbfolIXH2bitACRZYWAU.cache +0 -1
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/vk/vk-e_ORxd49RmmTia4r2ajyVw0p-xcUuz8uz8Nx_LUw.cache +0 -1
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/wa/wab9PO75nglTE-rq2pVPg22CRkZW_yTq_WcZ6BEp8T0.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/wd/wdHNDzQjfQYx2VQbObEoz4iNxGhcuum4uypNBmnuNpA.cache +0 -1
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/wu/wuO0z3wuhphrqHOHqZdrZd6lFv2u0_Gq7BkDoc_8cEw.cache +0 -1
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/x7/x7KkTV3ibfIEysLB_ug5bfmnn2VLV_BldukPR3EoPBk.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/xg/xge95XbE6Me8MVp8Pnz9FbKOZhvzndxHzh-uOjZV5_s.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/xz/Xz-wkd5XTDRNs5mNRhBpx4RSe0LN9ajplnuDcli51jE.cache +0 -1
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/xz/xzFhuo3m7qD5I9Xc85aP9j6kR-iAOB0najl9uu7hdMc.cache +0 -1
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/yn/ynGH6ruy4vPfFCwXOH8rgd3f-UWmo05h37jjH0cii8E.cache +0 -1
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/yw/yw6SDVVxzUeXqN9VX1eCGWTN809mt05p0JnedEBCZ7w.cache +0 -0
- 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:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: fcb725054d9ab842d48820c4ed9bdf01ac58ebaa48e7d49b4c5a1d6cb7cfaae5
|
4
|
+
data.tar.gz: 7cd69d44cd3905355dda875aee51639d772b9b72dd626feb366842a4fe702e72
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: eab9da6b041b2cc5f5975b943908754c2a8b212f7116f47432af4923c8ff78cb4eb7a36f7279ac597e408422247475832113f869da552f3c0e7f66e85889988c
|
7
|
+
data.tar.gz: e4c751bb2fdcbc44df09f2b01ef6ecd3d6fe267b466ae9ddbce07e17f3476d6fffec6b161577cd91f32525135165b9cd6f25bf89da560b8ec8be777cb9e5105d
|
data/README.md
CHANGED
@@ -1,46 +1,54 @@
|
|
1
1
|
# Rapidfire
|
2
|
-
[](https://codeclimate.com/github/code-mancers/rapidfire)
|
3
|
-
[](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
|
5
|
+
This gem supports:
|
8
6
|
|
9
|
-
|
10
|
-
|
7
|
+
- **rails**: 7.0, 7.1, 7.2 and 8.0
|
8
|
+
- **ruby**: 3.1, 3.2 and 3.3
|
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
|
-
|
16
|
+
|
17
|
+
Add this line to application's Gemfile:
|
14
18
|
|
15
19
|
```rb
|
16
|
-
|
20
|
+
gem 'rapidfire'
|
17
21
|
```
|
18
22
|
|
19
23
|
And then execute:
|
20
24
|
|
21
25
|
```shell
|
22
|
-
|
23
|
-
|
24
|
-
|
26
|
+
$ bundle install
|
27
|
+
$ bundle exec rake rapidfire:install:migrations
|
28
|
+
$ bundle exec rake db:migrate
|
25
29
|
```
|
26
30
|
|
27
|
-
|
31
|
+
Rapidfire views can also be customized. This command copies the views into `app/views` directory:
|
28
32
|
|
29
|
-
|
33
|
+
```sh
|
34
|
+
$ bundle exec rails generate rapidfire:views
|
35
|
+
```
|
30
36
|
|
31
|
-
|
37
|
+
Rapidfire locales (i18n) files can also be customized. The command is:
|
32
38
|
|
33
|
-
|
39
|
+
```sh
|
40
|
+
$ bundle exec rails generate rapidfire:locales
|
41
|
+
```
|
34
42
|
|
35
43
|
## Usage
|
36
44
|
|
37
|
-
Add this line to
|
45
|
+
Add this line to `config/routes.rb` file, thats good enough
|
38
46
|
|
39
47
|
```rb
|
40
|
-
|
48
|
+
mount Rapidfire::Engine => "/rapidfire"
|
41
49
|
```
|
42
50
|
|
43
|
-
|
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
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
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
|
67
|
-
|
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
|
-
|
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
|
-
|
113
|
+
localhost:3000/rapidfire/surveys/<survey-id>/attempts/new
|
93
114
|
```
|
94
115
|
|
95
|
-
|
96
|
-
|
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
|
-
|
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
|
-
|
146
|
+
GET /rapidfire/surveys/<survey-id>/results
|
124
147
|
```
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
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/codemancers/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
|
-
|
148
|
-
|
149
|
-
|
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
|
-
|
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
|
-
|
164
|
-
|
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
|
-
|
172
|
-
|
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
|
-
|
180
|
-
|
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
|
-
|
202
|
+
"Iran": 2
|
188
203
|
}
|
189
|
-
}
|
204
|
+
}
|
190
205
|
]
|
191
206
|
```
|
192
207
|
|
193
208
|
## How it works
|
194
|
-
|
195
|
-
|
196
|
-
|
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
|
201
|
-
2. Once
|
202
|
-
|
203
|
-
|
204
|
-
|
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,
|
226
|
-
|
227
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
257
|
-
|
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
|
-
|
292
|
+
# /<path-to-app>/config/initializers/rapidfire.rb
|
268
293
|
|
269
|
-
|
270
|
-
|
271
|
-
|
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
|
283
|
-
3. Commit
|
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
|
@@ -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:
|
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_'+
|
71
|
+
send 'current_' + rapidfire_scoped.to_s
|
72
72
|
end
|
73
73
|
end
|
74
74
|
end
|
@@ -3,19 +3,30 @@ module Rapidfire
|
|
3
3
|
before_action :authenticate_administrator!, except: :index
|
4
4
|
|
5
5
|
def index
|
6
|
-
@surveys =
|
7
|
-
|
8
|
-
|
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
|
-
|
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
|
-
|
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 <
|
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,12 +1,13 @@
|
|
1
1
|
module Rapidfire
|
2
|
-
class Question <
|
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
|
-
|
9
|
+
validate :type_can_change
|
10
|
+
serialize :validation_rules, coder: YAML
|
10
11
|
|
11
12
|
def self.inherited(child)
|
12
13
|
child.instance_eval do
|
@@ -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
|
-
|
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
|