binda 0.0.7 → 0.1.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.
Files changed (301) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +850 -18
  3. data/Rakefile +1 -13
  4. data/app/assets/javascripts/binda/application.js +23 -0
  5. data/app/assets/javascripts/binda/components/bootstrap.js +9 -0
  6. data/app/assets/javascripts/binda/components/field_group_editor.js +18 -0
  7. data/app/assets/javascripts/binda/components/fileupload.js +182 -0
  8. data/app/assets/javascripts/binda/components/form_item.js +91 -23
  9. data/app/assets/javascripts/binda/components/form_item_choice.js +15 -8
  10. data/app/assets/javascripts/binda/components/form_item_editor.js +6 -6
  11. data/app/assets/javascripts/binda/components/form_item_image.js +23 -0
  12. data/app/assets/javascripts/binda/components/form_item_repeater.js +70 -23
  13. data/app/assets/javascripts/binda/components/login-shader.js +193 -0
  14. data/app/assets/javascripts/binda/components/login_form.js +116 -0
  15. data/app/assets/javascripts/binda/components/radio-toggle.js +18 -0
  16. data/app/assets/javascripts/binda/components/select2.js +22 -0
  17. data/app/assets/javascripts/binda/components/sortable.js +53 -8
  18. data/app/assets/javascripts/binda/dist/binda.bundle.js +914 -107
  19. data/app/assets/javascripts/binda/index.js +26 -3
  20. data/app/assets/stylesheets/binda/application.scss +6 -0
  21. data/app/assets/stylesheets/binda/components/assets_manager.scss +46 -36
  22. data/app/assets/stylesheets/binda/components/b-btn.scss +114 -0
  23. data/app/assets/stylesheets/binda/components/button.scss +4 -1
  24. data/app/assets/stylesheets/binda/components/fileupload.scss +134 -0
  25. data/app/assets/stylesheets/binda/components/form_item.scss +233 -168
  26. data/app/assets/stylesheets/binda/components/form_item_image.scss +0 -0
  27. data/app/assets/stylesheets/binda/components/form_item_video.scss +25 -0
  28. data/app/assets/stylesheets/binda/components/main_container.scss +3 -0
  29. data/app/assets/stylesheets/binda/components/main_content.scss +1 -2
  30. data/app/assets/stylesheets/binda/components/main_header.scss +21 -20
  31. data/app/assets/stylesheets/binda/components/main_sidebar.scss +121 -0
  32. data/app/assets/stylesheets/binda/components/main_table.scss +84 -28
  33. data/app/assets/stylesheets/binda/components/popup_warning.scss +71 -0
  34. data/app/assets/stylesheets/binda/components/select2.scss +126 -0
  35. data/app/assets/stylesheets/binda/components/sortable.scss +83 -56
  36. data/app/assets/stylesheets/binda/components/standard-form.scss +228 -0
  37. data/app/assets/stylesheets/binda/components/texts.scss +6 -0
  38. data/app/assets/stylesheets/binda/controllers/components_index.scss +3 -0
  39. data/app/assets/stylesheets/binda/controllers/users_sessions_new.scss +309 -0
  40. data/app/assets/stylesheets/binda/index.scss +16 -8
  41. data/app/assets/stylesheets/binda/settings/bootstrap_overrides.scss +0 -0
  42. data/app/assets/stylesheets/binda/settings/buttons.scss +36 -0
  43. data/app/assets/stylesheets/binda/settings/common.scss +36 -79
  44. data/app/assets/stylesheets/binda/settings/fonts.scss +88 -31
  45. data/app/assets/stylesheets/binda/settings/tiny_mce_overrides.scss +82 -0
  46. data/app/assets/stylesheets/binda/settings/variables.scss +36 -31
  47. data/app/controllers/binda/application_controller.rb +0 -2
  48. data/app/controllers/binda/assets_controller.rb +1 -1
  49. data/app/controllers/binda/boards_controller.rb +15 -4
  50. data/app/controllers/binda/components_controller.rb +30 -15
  51. data/app/controllers/binda/field_groups_controller.rb +19 -4
  52. data/app/controllers/binda/images_controller.rb +68 -0
  53. data/app/controllers/binda/repeaters_controller.rb +3 -12
  54. data/app/controllers/binda/structures_controller.rb +8 -1
  55. data/app/controllers/binda/videos_controller.rb +68 -0
  56. data/app/controllers/concerns/binda/fieldable_helpers.rb +113 -28
  57. data/app/controllers/concerns/binda/maintenance_helpers.rb +34 -0
  58. data/app/helpers/binda/components_helper.rb +26 -2
  59. data/app/helpers/binda/field_groups_helper.rb +16 -0
  60. data/app/helpers/binda/structures_helper.rb +6 -0
  61. data/app/models/binda/asset.rb +0 -4
  62. data/app/models/binda/b.rb +5 -0
  63. data/app/models/binda/board.rb +1 -18
  64. data/app/models/binda/choice.rb +48 -12
  65. data/app/models/binda/component.rb +20 -0
  66. data/app/models/binda/field_group.rb +2 -2
  67. data/app/models/binda/field_setting.rb +61 -28
  68. data/app/models/binda/gallery.rb +0 -2
  69. data/app/models/binda/image.rb +7 -0
  70. data/app/models/binda/relation.rb +79 -0
  71. data/app/models/binda/relation_link.rb +11 -0
  72. data/app/models/binda/repeater.rb +1 -1
  73. data/app/models/binda/selection.rb +0 -9
  74. data/app/models/binda/structure.rb +41 -39
  75. data/app/models/binda/video.rb +7 -0
  76. data/app/models/concerns/binda/default_helpers.rb +186 -0
  77. data/app/models/concerns/binda/fieldable_associations.rb +276 -30
  78. data/app/uploaders/binda/{asset → image}/image_uploader.rb +27 -9
  79. data/app/uploaders/binda/video/video_uploader.rb +51 -0
  80. data/app/views/binda/boards/edit.html.erb +6 -1
  81. data/app/views/binda/categories/_form.html.erb +41 -40
  82. data/app/views/binda/categories/edit.html.erb +1 -1
  83. data/app/views/binda/categories/index.html.erb +16 -13
  84. data/app/views/binda/components/edit.html.erb +6 -3
  85. data/app/views/binda/components/index.html.erb +69 -28
  86. data/app/views/binda/components/new.html.erb +1 -1
  87. data/app/views/binda/components/sort_index.html.erb +46 -0
  88. data/app/views/binda/field_groups/_form_body.html.erb +65 -44
  89. data/app/views/binda/field_groups/_form_item.html.erb +66 -23
  90. data/app/views/binda/field_groups/_form_item_choice.erb +34 -15
  91. data/app/views/binda/field_groups/_form_section.html.erb +6 -10
  92. data/app/views/binda/field_groups/_form_section_repeater.html.erb +3 -3
  93. data/app/views/binda/field_groups/edit.html.erb +1 -1
  94. data/app/views/binda/field_settings/_form_body.html.erb +5 -5
  95. data/app/views/binda/field_settings/edit.html.erb +1 -1
  96. data/app/views/binda/fieldable/_form_body.html.erb +93 -79
  97. data/app/views/binda/fieldable/_form_item_date.html.erb +14 -14
  98. data/app/views/binda/fieldable/_form_item_image.html.erb +35 -0
  99. data/app/views/binda/fieldable/_form_item_new_repeater.html.erb +12 -5
  100. data/app/views/binda/fieldable/_form_item_relation.html.erb +44 -0
  101. data/app/views/binda/fieldable/_form_item_repeater.html.erb +80 -58
  102. data/app/views/binda/fieldable/_form_item_selections.html.erb +109 -87
  103. data/app/views/binda/fieldable/_form_item_string.html.erb +19 -17
  104. data/app/views/binda/fieldable/_form_item_text.html.erb +19 -16
  105. data/app/views/binda/fieldable/_form_item_video.html.erb +32 -0
  106. data/app/views/binda/fieldable/_form_section.html.erb +27 -5
  107. data/app/views/binda/fieldable/_form_section_repeater.html.erb +30 -10
  108. data/app/views/binda/fieldable/_form_sidebar.html.erb +44 -20
  109. data/app/views/binda/manage/users/_form_body.html.erb +42 -37
  110. data/app/views/binda/manage/users/edit.html.erb +1 -1
  111. data/app/views/binda/manage/users/index.html.erb +21 -21
  112. data/app/views/binda/structures/_form_body.html.erb +54 -60
  113. data/app/views/binda/structures/_form_section.html.erb +32 -18
  114. data/app/views/binda/structures/_form_sidebar.html.erb +35 -0
  115. data/app/views/binda/structures/edit.html.erb +2 -2
  116. data/app/views/binda/structures/index.html.erb +21 -16
  117. data/app/views/binda/structures/sort_index.html.erb +36 -0
  118. data/app/views/{users → binda/users}/confirmations/new.html.erb +1 -1
  119. data/app/views/{users → binda/users}/mailer/confirmation_instructions.html.erb +0 -0
  120. data/app/views/{users → binda/users}/mailer/password_change.html.erb +0 -0
  121. data/app/views/{users → binda/users}/mailer/reset_password_instructions.html.erb +0 -0
  122. data/app/views/{users → binda/users}/mailer/unlock_instructions.html.erb +0 -0
  123. data/app/views/{users → binda/users}/passwords/edit.html.erb +1 -1
  124. data/app/views/{users → binda/users}/passwords/new.html.erb +1 -1
  125. data/app/views/{users → binda/users}/registrations/edit.html.erb +0 -0
  126. data/app/views/{users → binda/users}/registrations/new.html.erb +1 -1
  127. data/app/views/binda/users/sessions/_background.html.erb +139 -0
  128. data/app/views/binda/users/sessions/new.html.erb +62 -0
  129. data/app/views/{users → binda/users}/shared/_links.html.erb +3 -3
  130. data/app/views/{users → binda/users}/unlocks/new.html.erb +1 -1
  131. data/app/views/kaminari/_first_page.html.erb +11 -0
  132. data/app/views/kaminari/_gap.html.erb +8 -0
  133. data/app/views/kaminari/_last_page.html.erb +11 -0
  134. data/app/views/kaminari/_next_page.html.erb +11 -0
  135. data/app/views/kaminari/_page.html.erb +12 -0
  136. data/app/views/kaminari/_paginator.html.erb +19 -0
  137. data/app/views/kaminari/_prev_page.html.erb +11 -0
  138. data/app/views/layouts/binda/_flash.html.erb +1 -1
  139. data/app/views/layouts/binda/_header.html.erb +2 -6
  140. data/app/views/layouts/binda/_sidebar.html.erb +11 -4
  141. data/app/views/layouts/binda/application.html.erb +15 -7
  142. data/config/autoprefixer.yml +5 -0
  143. data/config/database.yml.travis +3 -0
  144. data/config/initializers/assets.rb +1 -0
  145. data/config/initializers/autoprefixer.yml +5 -0
  146. data/config/initializers/carrierwave.rb +32 -0
  147. data/config/initializers/devise.rb +14 -10
  148. data/config/initializers/devise_patch.rb +8 -8
  149. data/config/initializers/simple_form.rb +4 -0
  150. data/config/initializers/simple_form__fileupload.rb +121 -0
  151. data/config/initializers/{simple_form_bootstrap.rb → simple_form_custom.rb} +79 -50
  152. data/config/locales/en.yml +61 -3
  153. data/config/locales/it.yml +51 -0
  154. data/config/locales/simple_form.en.yml +3 -3
  155. data/config/routes.rb +41 -24
  156. data/db/migrate/1_create_binda_tables.rb +18 -7
  157. data/db/migrate/20171214140451_add_preview_mode.rb +5 -0
  158. data/lib/binda.rb +1 -1
  159. data/lib/binda/engine.rb +19 -23
  160. data/lib/binda/version.rb +2 -2
  161. data/lib/generators/binda/install/install_generator.rb +59 -54
  162. data/lib/generators/binda/install/templates/config/initializers/carrierwave.rb +11 -2
  163. data/lib/generators/binda/maintenance/USAGE +8 -0
  164. data/lib/generators/binda/maintenance/maintenance_generator.rb +50 -0
  165. data/lib/generators/binda/maintenance/templates/app/assets/javascripts/maintenance.js +0 -0
  166. data/lib/generators/binda/maintenance/templates/app/assets/stylesheets/maintenance.scss +0 -0
  167. data/lib/generators/binda/maintenance/templates/app/views/layouts/maintenance.html.erb +16 -0
  168. data/lib/generators/binda/maintenance/templates/config/initializers/maintenance.rb +1 -0
  169. data/lib/generators/binda/setup/setup_generator.rb +41 -30
  170. data/lib/tasks/add_default_helpers_class_task.rake +11 -0
  171. data/lib/tasks/add_video_feature_task.rake +15 -0
  172. data/lib/tasks/remove_orphan_fields_task.rake +16 -0
  173. data/lib/tasks/set_repeater_position_task.rake +13 -0
  174. data/lib/tasks/upgrade_to_v007_task.rake +72 -0
  175. data/lib/tasks/user_tasks.rake +14 -0
  176. data/vendor/assets/fonts/font-awesome/fa-brands-400.eot +0 -0
  177. data/vendor/assets/fonts/font-awesome/fa-brands-400.svg +978 -0
  178. data/vendor/assets/fonts/font-awesome/fa-brands-400.ttf +0 -0
  179. data/vendor/assets/fonts/font-awesome/fa-brands-400.woff +0 -0
  180. data/vendor/assets/fonts/font-awesome/fa-brands-400.woff2 +0 -0
  181. data/vendor/assets/fonts/font-awesome/fa-regular-400.eot +0 -0
  182. data/vendor/assets/fonts/font-awesome/fa-regular-400.svg +363 -0
  183. data/vendor/assets/fonts/font-awesome/fa-regular-400.ttf +0 -0
  184. data/vendor/assets/fonts/font-awesome/fa-regular-400.woff +0 -0
  185. data/vendor/assets/fonts/font-awesome/fa-regular-400.woff2 +0 -0
  186. data/vendor/assets/fonts/font-awesome/fa-solid-900.eot +0 -0
  187. data/vendor/assets/fonts/font-awesome/fa-solid-900.svg +1410 -0
  188. data/vendor/assets/fonts/font-awesome/fa-solid-900.ttf +0 -0
  189. data/vendor/assets/fonts/font-awesome/fa-solid-900.woff +0 -0
  190. data/vendor/assets/fonts/font-awesome/fa-solid-900.woff2 +0 -0
  191. data/vendor/assets/javascripts/GSAP/CSSPlugin.min.js +13 -0
  192. data/vendor/assets/javascripts/GSAP/EasePack.min.js +12 -0
  193. data/vendor/assets/javascripts/GSAP/ScrollToPlugin.min.js +12 -0
  194. data/vendor/assets/javascripts/GSAP/TweenLite.min.js +12 -0
  195. data/vendor/assets/javascripts/select2/i18n/af.js +3 -0
  196. data/vendor/assets/javascripts/select2/i18n/ar.js +3 -0
  197. data/vendor/assets/javascripts/select2/i18n/az.js +3 -0
  198. data/vendor/assets/javascripts/select2/i18n/bg.js +3 -0
  199. data/vendor/assets/javascripts/select2/i18n/bs.js +3 -0
  200. data/vendor/assets/javascripts/select2/i18n/ca.js +3 -0
  201. data/vendor/assets/javascripts/select2/i18n/cs.js +3 -0
  202. data/vendor/assets/javascripts/select2/i18n/da.js +3 -0
  203. data/vendor/assets/javascripts/select2/i18n/de.js +3 -0
  204. data/vendor/assets/javascripts/select2/i18n/dsb.js +3 -0
  205. data/vendor/assets/javascripts/select2/i18n/el.js +3 -0
  206. data/vendor/assets/javascripts/select2/i18n/en.js +3 -0
  207. data/vendor/assets/javascripts/select2/i18n/es.js +3 -0
  208. data/vendor/assets/javascripts/select2/i18n/et.js +3 -0
  209. data/vendor/assets/javascripts/select2/i18n/eu.js +3 -0
  210. data/vendor/assets/javascripts/select2/i18n/fa.js +3 -0
  211. data/vendor/assets/javascripts/select2/i18n/fi.js +3 -0
  212. data/vendor/assets/javascripts/select2/i18n/fr.js +3 -0
  213. data/vendor/assets/javascripts/select2/i18n/gl.js +3 -0
  214. data/vendor/assets/javascripts/select2/i18n/he.js +3 -0
  215. data/vendor/assets/javascripts/select2/i18n/hi.js +3 -0
  216. data/vendor/assets/javascripts/select2/i18n/hr.js +3 -0
  217. data/vendor/assets/javascripts/select2/i18n/hsb.js +3 -0
  218. data/vendor/assets/javascripts/select2/i18n/hu.js +3 -0
  219. data/vendor/assets/javascripts/select2/i18n/hy.js +3 -0
  220. data/vendor/assets/javascripts/select2/i18n/id.js +3 -0
  221. data/vendor/assets/javascripts/select2/i18n/is.js +3 -0
  222. data/vendor/assets/javascripts/select2/i18n/it.js +3 -0
  223. data/vendor/assets/javascripts/select2/i18n/ja.js +3 -0
  224. data/vendor/assets/javascripts/select2/i18n/km.js +3 -0
  225. data/vendor/assets/javascripts/select2/i18n/ko.js +3 -0
  226. data/vendor/assets/javascripts/select2/i18n/lt.js +3 -0
  227. data/vendor/assets/javascripts/select2/i18n/lv.js +3 -0
  228. data/vendor/assets/javascripts/select2/i18n/mk.js +3 -0
  229. data/vendor/assets/javascripts/select2/i18n/ms.js +3 -0
  230. data/vendor/assets/javascripts/select2/i18n/nb.js +3 -0
  231. data/vendor/assets/javascripts/select2/i18n/nl.js +3 -0
  232. data/vendor/assets/javascripts/select2/i18n/pl.js +3 -0
  233. data/vendor/assets/javascripts/select2/i18n/ps.js +3 -0
  234. data/vendor/assets/javascripts/select2/i18n/pt-BR.js +3 -0
  235. data/vendor/assets/javascripts/select2/i18n/pt.js +3 -0
  236. data/vendor/assets/javascripts/select2/i18n/ro.js +3 -0
  237. data/vendor/assets/javascripts/select2/i18n/ru.js +3 -0
  238. data/vendor/assets/javascripts/select2/i18n/sk.js +3 -0
  239. data/vendor/assets/javascripts/select2/i18n/sl.js +3 -0
  240. data/vendor/assets/javascripts/select2/i18n/sr-Cyrl.js +3 -0
  241. data/vendor/assets/javascripts/select2/i18n/sr.js +3 -0
  242. data/vendor/assets/javascripts/select2/i18n/sv.js +3 -0
  243. data/vendor/assets/javascripts/select2/i18n/th.js +3 -0
  244. data/vendor/assets/javascripts/select2/i18n/tr.js +3 -0
  245. data/vendor/assets/javascripts/select2/i18n/uk.js +3 -0
  246. data/vendor/assets/javascripts/select2/i18n/vi.js +3 -0
  247. data/vendor/assets/javascripts/select2/i18n/zh-CN.js +3 -0
  248. data/vendor/assets/javascripts/select2/i18n/zh-TW.js +3 -0
  249. data/vendor/assets/javascripts/select2/select2.full.min.js +1 -0
  250. data/vendor/assets/javascripts/select2/select2.min.js +1 -0
  251. data/vendor/assets/javascripts/tether.min.js +1 -0
  252. data/vendor/assets/stylesheets/{bootstrap-select.css → bootstrap/bootstrap-select.css} +0 -0
  253. data/vendor/assets/stylesheets/font-awesome/_animated.scss +6 -20
  254. data/vendor/assets/stylesheets/font-awesome/_bordered-pulled.scss +6 -11
  255. data/vendor/assets/stylesheets/font-awesome/_core.scss +11 -7
  256. data/vendor/assets/stylesheets/font-awesome/_fixed-width.scss +1 -1
  257. data/vendor/assets/stylesheets/font-awesome/_icons.scss +785 -787
  258. data/vendor/assets/stylesheets/font-awesome/_larger.scss +16 -6
  259. data/vendor/assets/stylesheets/font-awesome/_list.scss +7 -8
  260. data/vendor/assets/stylesheets/font-awesome/_mixins.scss +17 -20
  261. data/vendor/assets/stylesheets/font-awesome/_rotated-flipped.scss +9 -6
  262. data/vendor/assets/stylesheets/font-awesome/_screen-reader.scss +2 -2
  263. data/vendor/assets/stylesheets/font-awesome/_stacked.scss +19 -8
  264. data/vendor/assets/stylesheets/font-awesome/_variables.scss +795 -795
  265. data/vendor/assets/stylesheets/font-awesome/fa-brands.scss +21 -0
  266. data/vendor/assets/stylesheets/font-awesome/fa-regular.scss +22 -0
  267. data/vendor/assets/stylesheets/font-awesome/fa-solid.scss +23 -0
  268. data/vendor/assets/stylesheets/font-awesome/fontawesome.scss +20 -0
  269. data/vendor/assets/stylesheets/select2/select2.min.css +1 -0
  270. metadata +278 -125
  271. data/app/assets/javascripts/binda/components/form_item_asset.js +0 -25
  272. data/app/assets/stylesheets/binda/application.css +0 -6
  273. data/app/assets/stylesheets/binda/components/form_body.scss +0 -2
  274. data/app/assets/stylesheets/binda/components/form_item_asset.scss +0 -20
  275. data/app/assets/stylesheets/binda/components/form_section.scss +0 -40
  276. data/app/assets/stylesheets/binda/components/sidebar.scss +0 -131
  277. data/app/assets/stylesheets/binda/layout/components_index.scss +0 -9
  278. data/app/assets/stylesheets/binda/layout/dashboard.scss +0 -7
  279. data/app/assets/stylesheets/binda/layout/users_sign_in.scss +0 -29
  280. data/app/controllers/binda/bindings_controller.rb +0 -62
  281. data/app/controllers/concerns/binda/default_helpers.rb +0 -226
  282. data/app/helpers/binda/bindings_helper.rb +0 -4
  283. data/app/models/binda/binda.rb +0 -7
  284. data/app/models/binda/binding.rb +0 -24
  285. data/app/views/binda/bindings/_form.html.erb +0 -32
  286. data/app/views/binda/bindings/edit.html.erb +0 -6
  287. data/app/views/binda/bindings/index.html.erb +0 -31
  288. data/app/views/binda/bindings/new.html.erb +0 -5
  289. data/app/views/binda/bindings/show.html.erb +0 -19
  290. data/app/views/binda/field_groups/index.html.erb +0 -34
  291. data/app/views/binda/fieldable/_form_item_asset.html.erb +0 -20
  292. data/app/views/users/sessions/new.html.erb +0 -27
  293. data/lib/tasks/binda.rake +0 -79
  294. data/vendor/assets/fonts/font-awesome/FontAwesome.otf +0 -0
  295. data/vendor/assets/fonts/font-awesome/fontawesome-webfont.eot +0 -0
  296. data/vendor/assets/fonts/font-awesome/fontawesome-webfont.svg +0 -2671
  297. data/vendor/assets/fonts/font-awesome/fontawesome-webfont.ttf +0 -0
  298. data/vendor/assets/fonts/font-awesome/fontawesome-webfont.woff +0 -0
  299. data/vendor/assets/fonts/font-awesome/fontawesome-webfont.woff2 +0 -0
  300. data/vendor/assets/stylesheets/font-awesome/_path.scss +0 -15
  301. data/vendor/assets/stylesheets/font-awesome/font-awesome.scss +0 -18
@@ -3,42 +3,127 @@ module Binda
3
3
 
4
4
  extend ActiveSupport::Concern
5
5
 
6
- # Only allow a trusted parameter "white list" through.
7
- def fieldable_params
8
- [ texts_attributes: [ :id, :field_setting_id, :fieldable_type, :fieldable_id, :content ],
6
+ # Only allow a trusted parameter "white list" through.
7
+ def fieldable_params
8
+ [ texts_attributes: [ :id, :field_setting_id, :fieldable_type, :fieldable_id, :content ],
9
+ strings_attributes: [ :id, :field_setting_id, :fieldable_type, :fieldable_id, :content ],
10
+ images_attributes: [ :id, :field_setting_id, :fieldable_type, :fieldable_id, :image, :image_cache ],
11
+ videos_attributes: [ :id, :field_setting_id, :fieldable_type, :fieldable_id, :video, :video_cache ],
12
+ dates_attributes: [ :id, :field_setting_id, :fieldable_type, :fieldable_id, :date ],
13
+ galleries_attributes: [ :id, :field_setting_id, :fieldable_type, :fieldable_id ],
14
+ radios_attributes: [ :id, :field_setting_id, :fieldable_type, :fieldable_id, :choice_ids ],
15
+ selections_attributes: [ :id, :field_setting_id, :fieldable_type, :fieldable_id, :choice_ids ],
16
+ checkboxes_attributes: [ :id, :field_setting_id, :fieldable_type, :fieldable_id, choice_ids: [] ],
17
+ relations_attributes: [ :id, :field_setting_id, :fieldable_type, :fieldable_id, dependent_component_ids: [], parent_related_board_ids: [] ],
18
+ repeaters_attributes: [ :id, :field_setting_id, :fieldable_type, :fieldable_id, :field_group_id,
19
+ texts_attributes: [ :id, :field_setting_id, :fieldable_type, :fieldable_id, :content ],
9
20
  strings_attributes: [ :id, :field_setting_id, :fieldable_type, :fieldable_id, :content ],
10
- assets_attributes: [ :id, :field_setting_id, :fieldable_type, :fieldable_id, :image ],
21
+ images_attributes: [ :id, :field_setting_id, :fieldable_type, :fieldable_id, :image, :image_cache ],
22
+ videos_attributes: [ :id, :field_setting_id, :fieldable_type, :fieldable_id, :video, :video_cache ],
11
23
  dates_attributes: [ :id, :field_setting_id, :fieldable_type, :fieldable_id, :date ],
12
24
  galleries_attributes: [ :id, :field_setting_id, :fieldable_type, :fieldable_id ],
25
+ relations_attributes: [ :id, :field_setting_id, :fieldable_type, :fieldable_id, dependent_component_ids: [], parent_related_board_ids: [] ],
26
+ repeaters_attributes: [ :id, :field_setting_id, :fieldable_type, :fieldable_id, :field_group_id ],
13
27
  radios_attributes: [ :id, :field_setting_id, :fieldable_type, :fieldable_id, :choice_ids ],
14
28
  selections_attributes: [ :id, :field_setting_id, :fieldable_type, :fieldable_id, :choice_ids ],
15
- checkboxes_attributes: [ :id, :field_setting_id, :fieldable_type, :fieldable_id, choice_ids: [] ],
16
- repeaters_attributes: [ :id, :field_setting_id, :fieldable_type, :fieldable_id, :field_group_id,
17
- texts_attributes: [ :id, :field_setting_id, :fieldable_type, :fieldable_id, :content ],
18
- assets_attributes: [ :id, :field_setting_id, :fieldable_type, :fieldable_id, :image ],
19
- dates_attributes: [ :id, :field_setting_id, :fieldable_type, :fieldable_id, :date ],
20
- galleries_attributes: [ :id, :field_setting_id, :fieldable_type, :fieldable_id ],
21
- repeaters_attributes: [ :id, :field_setting_id, :fieldable_type, :fieldable_id, :field_group_id ],
22
- radios_attributes: [ :id, :field_setting_id, :fieldable_type, :fieldable_id, :choice_ids ],
23
- selections_attributes: [ :id, :field_setting_id, :fieldable_type, :fieldable_id, :choice_ids ],
24
- checkboxes_attributes: [ :id, :field_setting_id, :fieldable_type, :fieldable_id, choice_ids: [] ]
25
- ]]
29
+ checkboxes_attributes: [ :id, :field_setting_id, :fieldable_type, :fieldable_id, choice_ids: [] ]
30
+ ]]
31
+ end
32
+
33
+ # Uploads parameters.
34
+ #
35
+ # @param fieldable_type {symbol} It can be `:component` or `:board`.
36
+ #
37
+ # @return {hash} It returns a hash with the permitted upload parameters
38
+ #
39
+ def upload_params fieldable_type
40
+ params.require(fieldable_type).permit(
41
+ :id, :name, :slug, :position, :publish_state, :structure_id, :category_ids,
42
+ {structure_attributes: [ :id ]},
43
+ {categories_attributes: [ :id, :category_id ]},
44
+ {images_attributes: [ :id, :field_setting_id, :fieldable_type, :fieldable_id, :image, :image_cache ]},
45
+ {videos_attributes: [ :id, :field_setting_id, :fieldable_type, :fieldable_id, :video, :video_cache ]},
46
+ {repeaters_attributes: [ :id, :field_setting_id, :fieldable_type, :fieldable_id,
47
+ images_attributes: [ :id, :field_setting_id, :fieldable_type, :fieldable_id, :image, :image_cache ],
48
+ videos_attributes: [ :id, :field_setting_id, :fieldable_type, :fieldable_id, :video, :video_cache ]]})
49
+ end
50
+
51
+ # Uploads a details for a fieldable instance (component or board)
52
+ #
53
+ # @return {hash} containig the array of images
54
+ #
55
+ # @example The return value will be something like:
56
+ # # Return hash
57
+ # {
58
+ # name: 'my_image.png',
59
+ # size: 543876,
60
+ # width: 300,
61
+ # height: 300,
62
+ # url: 'url/to/my_image.png',
63
+ # thumbnailUrl: 'url/to/my_image_thumb.png'
64
+ # }
65
+ #
66
+ def upload_details
67
+
68
+ # Because this is a callback that happens right after the upload
69
+ # chances are that it's also the latest asset that has been updated.
70
+ # Therefore get the latest uploaded asset
71
+ asset = Asset.order('updated_at').last
72
+
73
+ if asset.image.present? && asset.video.present?
74
+ raise "The record Binda::Asset with id=#{asset.id} has both image and video attached. This might have been caused by updating the record outside Binda's interface. Please make sure this record has either an image or a video."
75
+ elsif asset.image.present?
76
+ return_image_details(asset)
77
+ elsif asset.video.present?
78
+ return_video_details(asset)
79
+ else
80
+ raise "The record Binda::Asset with id=#{asset.id} doesn't have any image or video attached. This might be due to a bug. Please report it in Binda official Github page."
26
81
  end
82
+ end
27
83
 
28
- def repeater_params
29
- params.require(:repeater).permit(
30
- new_repeaters_attributes: [ :id, :field_setting_id, :field_group_id, :fieldable_type, :fieldable_id,
31
- texts_attributes: [ :id, :field_setting_id, :fieldable_type, :fieldable_id, :content ],
32
- strings_attributes: [ :id, :field_setting_id, :fieldable_type, :fieldable_id, :content ],
33
- assets_attributes: [ :id, :field_setting_id, :fieldable_type, :fieldable_id, :image ],
34
- dates_attributes: [ :id, :field_setting_id, :fieldable_type, :fieldable_id, :date ],
35
- galleries_attributes: [ :id, :field_setting_id, :fieldable_type, :fieldable_id ],
36
- repeaters_attributes: [ :id, :field_setting_id, :field_group_id, :fieldable_type, :fieldable_id ],
37
- radios_attributes: [ :id, :field_setting_id, :fieldable_type, :fieldable_id, :choice_ids ],
38
- selections_attributes: [ :id, :field_setting_id, :fieldable_type, :fieldable_id, :choice_ids ],
39
- checkboxes_attributes: [ :id, :field_setting_id, :fieldable_type, :fieldable_id, choice_ids: [] ]
40
- ])
84
+
85
+ # Return image details
86
+ #
87
+ # This helper is used internally by the `upload_details` method
88
+ # to retrieve and return the necessary details to be displayed on
89
+ # the editor.
90
+ def return_image_details asset
91
+ # get image dimension
92
+ if CarrierWave::Uploader::Base.storage == CarrierWave::Storage::File
93
+ file = MiniMagick::Image.open(::Rails.root.join(asset.image.path))
94
+ else
95
+ file = MiniMagick::Image.open(asset.image.url)
41
96
  end
97
+ return {
98
+ type: 'image',
99
+ name: asset.image_identifier,
100
+ size: "#{bytes_to_megabytes( asset.image.size )}MB",
101
+ width: file.width,
102
+ height: file.height,
103
+ url: asset.image.url,
104
+ thumbnailUrl: asset.image.thumb.url
105
+ }
106
+ end
107
+
108
+
109
+ # Return video details
110
+ #
111
+ # This helper is used internally by the `upload_details` method
112
+ # to retrieve and return the necessary details to be displayed on
113
+ # the editor.
114
+ def return_video_details asset
115
+ return {
116
+ type: 'video',
117
+ name: asset.video_identifier,
118
+ size: "#{bytes_to_megabytes( asset.video.size )}MB",
119
+ url: asset.video.url,
120
+ ext: asset.video.file.extension.downcase
121
+ }
122
+ end
42
123
 
124
+ # Convert bytes to megabites
125
+ def bytes_to_megabytes bytes
126
+ (bytes.to_f / 1.megabyte).round(2)
127
+ end
43
128
  end
44
129
  end
@@ -0,0 +1,34 @@
1
+ module Binda
2
+ module MaintenanceHelpers
3
+
4
+ extend ActiveSupport::Concern
5
+
6
+ included do
7
+ before_action :force_redirect
8
+ layout :get_layout
9
+ end
10
+
11
+ def is_maintenance_mode
12
+ if B.get_boards('dashboard').includes(:radios).first.get_radio_choice('maintenance-mode')[:value] == 'true' && !user_signed_in?
13
+ return true
14
+ else
15
+ return false
16
+ end
17
+ end
18
+
19
+ private
20
+
21
+ def get_layout
22
+ if is_maintenance_mode
23
+ 'maintenance'
24
+ else
25
+ 'application'
26
+ end
27
+ end
28
+
29
+ def force_redirect
30
+ return redirect_to maintenance_path if request.original_url != maintenance_url && is_maintenance_mode
31
+ end
32
+
33
+ end
34
+ end
@@ -1,5 +1,29 @@
1
1
  module Binda
2
- module ComponentsHelper
2
+ module ComponentsHelper
3
3
 
4
- end
4
+ # Get the sort index link
5
+ #
6
+ # This helper generate the a link to the page where to sort components, or
7
+ # a broken link that tells you that you have too many components to go to that page.
8
+ def get_sort_index_link
9
+ if @structure.components.length < Component.sort_limit
10
+ link_to "<i class=\"fa fa-random\" aria-hidden=\"true\"></i>Sort #{ @structure.name.humanize.split.map(&:capitalize).join(' ').pluralize }".html_safe, structure_components_sort_index_path, class: 'main-header--link b-btn b-btn-primary'
11
+ else
12
+ link_to "Sort #{ @structure.name.humanize.split.map(&:capitalize).join(' ').pluralize }", '#', class: 'main-header--link b-btn b-btn-primary', onclick: "alert(\"Sorry! It's not possible to sort #{@structure.name.pluralize} anymore. You currently have more than #{Component.sort_limit} #{@structure.name.pluralize} which is the maximum limit.\")"
13
+ end
14
+ end
15
+
16
+ # Prepare description for form hint
17
+ #
18
+ # This helper return the field description (as `string`) or false (as `boolean`)
19
+ # in order to tell Simple Form whether to generate or not the hint html tag.
20
+ def prepare_description_for_form_hint field_setting
21
+ if field_setting.description.blank?
22
+ return false
23
+ else
24
+ return field_setting.description
25
+ end
26
+ end
27
+
28
+ end
5
29
  end
@@ -6,5 +6,21 @@ module Binda
6
6
  return structure_field_group_path if action_name == 'edit'
7
7
  end
8
8
 
9
+ def get_relationable_components field_setting
10
+ if @instance.class.to_s == 'Binda::Component'
11
+ Binda::Component.where( structure_id: Binda::Structure.where( id: field_setting.accepted_structure_ids )).where.not(id: @instance.id)
12
+ elsif @instance.class.to_s == 'Binda::Board'
13
+ Binda::Component.where( structure_id: Binda::Structure.where( id: field_setting.accepted_structure_ids ))
14
+ end
15
+ end
16
+
17
+ def get_relationable_boards field_setting
18
+ if @instance.class.to_s == 'Binda::Component'
19
+ Binda::Board.where( structure_id: Binda::Structure.where( id: field_setting.accepted_structure_ids ))
20
+ elsif @instance.class.to_s == 'Binda::Board'
21
+ Binda::Board.where( structure_id: Binda::Structure.where( id: field_setting.accepted_structure_ids )).where.not(id: @instance.id)
22
+ end
23
+ end
24
+
9
25
  end
10
26
  end
@@ -1,4 +1,10 @@
1
1
  module Binda
2
2
  module StructuresHelper
3
+
4
+ def get_structures_sort_index_link
5
+
6
+ link_to "<i class=\"fa fa-random\" aria-hidden=\"true\"></i>Sort Structures".html_safe, structures_sort_index_path, class: 'main-header--link b-btn b-btn-primary'
7
+ end
8
+
3
9
  end
4
10
  end
@@ -2,12 +2,8 @@ module Binda
2
2
  class Asset < ApplicationRecord
3
3
 
4
4
  # Associations
5
- has_many :bindings
6
- has_many :galleries, through: :bindings
7
5
  belongs_to :fieldable, polymorphic: true
8
6
  belongs_to :field_setting
9
7
 
10
- mount_uploader :image, ImageUploader
11
-
12
8
  end
13
9
  end
@@ -0,0 +1,5 @@
1
+ module Binda
2
+ class B < ApplicationRecord
3
+ include DefaultHelpers
4
+ end
5
+ end
@@ -3,7 +3,7 @@ module Binda
3
3
 
4
4
  include FieldableAssociations
5
5
 
6
- belongs_to :structure, required: true
6
+ belongs_to :structure, required: true
7
7
 
8
8
  validates :name, presence: true
9
9
  validates :slug, uniqueness: true
@@ -20,22 +20,5 @@ module Binda
20
20
  slug.blank?
21
21
  end
22
22
 
23
- # def self.website_name
24
- # self.all.find { |s| s.slug == 'website-name' }
25
- # end
26
-
27
- # def self.website_description
28
- # self.all.find { |s| s.slug == 'website-description' }
29
- # end
30
-
31
- # def self.maintenance_mode
32
- # self.all.find { |s| s.slug == 'maintenance-mode' }
33
- # end
34
-
35
- # def self.is_maintenance_mode
36
- # # maybe this should have question mark at the end...
37
- # self.maintenance_mode.is_true
38
- # end
39
-
40
23
  end
41
24
  end
@@ -16,23 +16,59 @@ module Binda
16
16
  # If there isn't a default it sets the current choice as the default one.
17
17
  # The method is executed as well if new choices are added.
18
18
  def set_default_choice
19
- unless self.field_setting.default_choice.present?
20
- self.field_setting.default_choice_id = self.id
21
- unless self.field_setting.save
22
- raise ArgumentError "It hasn't been possible to set the default choice for the current setting."
23
- end
19
+
20
+ # Make sure you are referring to the updated ActiveRecord object where the choice has already been deleted
21
+ # Infact: self.field_setting != FieldSetting.find( self.field_setting.id )
22
+ field_setting = FieldSetting.find(self.field_setting.id)
23
+
24
+ # unless Choice.find(field_setting.default_choice_id).present?
25
+ return unless field_setting.default_choice_id.nil?
26
+ field_setting.default_choice_id = self.id
27
+ unless field_setting.save
28
+ raise "It hasn't been possible to set the default choice for the current setting (#{field_setting.slug})."
24
29
  end
25
30
  end
26
31
 
27
- # In order to make sure that a default choice is set, this method is executed after the
32
+ # In order to make sure a default choice is set, this method is executed after the
28
33
  # default choice is removed. What does it do? If the removed choice is the default one it sets
29
- # another defautl picking the first of the choices associated by id.
30
- # The method is executed as well on every time a choice is removed.
34
+ # another defautl picking the first of the choices associated by id.
35
+ # Once done, update all associated records that now don't have the any associated choice.
31
36
  def reset_default_choice
32
- if self.field_setting.default_choice_id == self.id && self.field_setting.choices.any?
33
- self.field_setting.default_choice_id = self.field_setting.choices.first.id
34
- unless self.field_setting.save
35
- raise ArgumentError "It hasn't been possible to set the default choice for the current setting."
37
+
38
+ # Make sure you are referring to the updated ActiveRecord object where the choice has already been deleted
39
+ # Infact: self.field_setting != FieldSetting.find( self.field_setting.id )
40
+ field_setting = FieldSetting.find(self.field_setting.id)
41
+
42
+ # Don't do anything if the default choice isn't the one we just destroyed
43
+ return if field_setting.choice_ids.include? field_setting.default_choice_id
44
+
45
+ # Make sure the default choice is needed
46
+ return if field_setting.allow_null? && field_setting.field_type != 'radio'
47
+
48
+
49
+ if field_setting.choices.any?
50
+ # Mark as default choice the first choice available
51
+ field_setting.default_choice_id = field_setting.choices.first.id
52
+ else
53
+ # Remove default choice setting (which at this point is the current choice (self))
54
+ field_setting.default_choice_id = nil
55
+ end
56
+
57
+ # Save and check if it's alright
58
+ unless field_setting.save
59
+ raise "It hasn't been possible to set the default choice for the current setting (#{field_setting.slug})."
60
+ end
61
+
62
+ # Create an empty array in order to avoid generating an error on the following each loop
63
+ selections = Selection.joins(:field_setting).where(binda_field_settings: {id: field_setting.id })
64
+
65
+ # Make sure none of the Binda::Selection instances (radios/checkboxes/selects) are left without a choice
66
+ selections.each do |selection|
67
+ unless selection.choices.any?
68
+ selection.choices << Choice.find(self.field_setting.default_choice_id)
69
+ unless selection.save
70
+ raise "It hasn't been possible to set the default choice for Binda::Selection with id=#{selection.id}"
71
+ end
36
72
  end
37
73
  end
38
74
  end
@@ -4,6 +4,7 @@ module Binda
4
4
  include FieldableAssociations
5
5
 
6
6
  # Associations
7
+
7
8
  belongs_to :structure, required: true
8
9
  has_and_belongs_to_many :categories
9
10
 
@@ -14,6 +15,8 @@ module Binda
14
15
 
15
16
  accepts_nested_attributes_for :categories, allow_destroy: true
16
17
 
18
+ after_create :set_position
19
+
17
20
  # Slug
18
21
  extend FriendlyId
19
22
  friendly_id :name, use: [:slugged, :finders]
@@ -43,5 +46,22 @@ module Binda
43
46
  slug.blank?
44
47
  end
45
48
 
49
+ # The limit above which componets cannot be sorted anymore
50
+ def self.sort_limit
51
+ 1000
52
+ end
53
+
54
+ private
55
+
56
+ # By default a newly created component gets the last position
57
+ def set_position
58
+ # check whats the latest component
59
+ last_position = self.structure.components.order(:position).pluck(:position).last
60
+ # if latest component position isn't set get position by counting the amount of components
61
+ last_position = self.structure.components.length if last_position.nil?
62
+ # update component
63
+ self.update_attributes(position: last_position + 1)
64
+ end
65
+
46
66
  end
47
67
  end
@@ -6,7 +6,7 @@ module Binda
6
6
 
7
7
  # use destroy not delete_all otherwise the field settings
8
8
  # won't be able to delete all their dependent content
9
- has_many :field_settings, dependent: :delete_all
9
+ has_many :field_settings, dependent: :destroy
10
10
 
11
11
  # Validations
12
12
  validates :name, presence: true
@@ -24,7 +24,7 @@ module Binda
24
24
  # Method inherited from friendly id
25
25
  # @see https://github.com/norman/friendly_id/issues/436
26
26
  def should_generate_new_friendly_id?
27
- slug.blank? || name_changed?
27
+ slug.blank?
28
28
  end
29
29
 
30
30
  # Set slug name
@@ -1,10 +1,12 @@
1
1
  module Binda
2
2
  class FieldSetting < ApplicationRecord
3
3
 
4
- # Associations
5
4
  belongs_to :field_group
6
5
  has_ancestry orphan_strategy: :destroy
7
6
 
7
+ # Is this reallly needed? Or can we just use accepted_structures?
8
+ # has_and_belongs_to_many :structures
9
+
8
10
  # Fields Associations
9
11
  #
10
12
  # If you add a new field remember to update:
@@ -15,31 +17,36 @@ module Binda
15
17
  has_many :dates, as: :fieldable
16
18
  has_many :galleries, as: :fieldable
17
19
  has_many :assets, as: :fieldable
18
- has_many :repeater, as: :fieldable
19
- has_many :radio, as: :fieldable
20
- has_many :selection, as: :fieldable
21
- has_many :checkbox, as: :fieldable
22
-
23
-
24
- # The following direct association is used to securely delete associated fields
20
+ has_many :images, as: :fieldable
21
+ has_many :videos, as: :fieldable
22
+ has_many :repeaters, as: :fieldable
23
+ has_many :radios, as: :fieldable
24
+ has_many :selections, as: :fieldable
25
+ has_many :checkboxes, as: :fieldable
26
+ has_many :relations, as: :fieldable
27
+
28
+ # The following direct associations are used to securely delete associated fields
25
29
  # Infact via `fieldable` the associated fields might not be deleted
26
30
  # as the fieldable_id is related to the `component`, `board` or `repeater` rather than `field_setting`
27
- has_many :texts, dependent: :delete_all
28
- has_many :strings, dependent: :delete_all
29
- has_many :dates, dependent: :delete_all
30
- has_many :galleries, dependent: :delete_all
31
- has_many :repeater, dependent: :delete_all
32
- has_many :radio, dependent: :delete_all
33
- has_many :selection, dependent: :delete_all
34
- has_many :checkbox, dependent: :delete_all
35
-
36
- has_many :choices, dependent: :delete_all
31
+ has_many :texts, dependent: :destroy
32
+ has_many :strings, dependent: :destroy
33
+ has_many :dates, dependent: :destroy
34
+ has_many :galleries, dependent: :destroy
35
+ has_many :repeaters, dependent: :destroy
36
+ has_many :radios, dependent: :destroy
37
+ has_many :selections, dependent: :destroy
38
+ has_many :checkboxes, dependent: :destroy
39
+ has_many :relations, dependent: :destroy
40
+
41
+ has_many :choices, dependent: :destroy
37
42
  has_one :default_choice, -> (field_setting) { where(id: field_setting.default_choice_id) }, class_name: 'Binda::Choice'
43
+
44
+ has_and_belongs_to_many :accepted_structures, class_name: 'Binda::Structure'
38
45
 
39
- accepts_nested_attributes_for :choices, allow_destroy: true, reject_if: :is_rejected
46
+ accepts_nested_attributes_for :accepted_structures, :texts, :strings, :dates, :galleries,
47
+ :assets, :images, :videos, :repeaters, :radios, :selections,
48
+ :checkboxes, :relations, :choices, allow_destroy: true, reject_if: :is_rejected
40
49
 
41
-
42
- #
43
50
  # Sets the validation rules to accept and save an attribute
44
51
  def is_rejected( attributes )
45
52
  attributes['label'].blank? || attributes['content'].blank?
@@ -47,10 +54,10 @@ module Binda
47
54
 
48
55
  cattr_accessor :field_settings_array
49
56
 
50
- after_create :set_allow_null
51
-
52
57
  after_create do
53
58
  self.class.reset_field_settings_array
59
+ set_allow_null
60
+ create_field_instances
54
61
  end
55
62
 
56
63
  after_destroy do
@@ -58,13 +65,12 @@ module Binda
58
65
  end
59
66
 
60
67
  def self.get_field_classes
61
- %w( String Text Date Asset Repeater Radio Selection Checkbox )
68
+ %w( String Text Date Image Video Repeater Radio Selection Checkbox Relation )
62
69
  end
63
70
 
64
71
  # Validations
65
72
  validates :name, presence: true
66
- validates :field_type, presence: true
67
- validates :field_type, inclusion: { in: [ *FieldSetting.get_field_classes.map{ |fc| fc.to_s.underscore }, '' ], message: "Field type must be one of the following #{ FieldSetting.get_field_classes.join(", ") }" }
73
+ validates :field_type, inclusion: { in: [ *FieldSetting.get_field_classes.map{ |fc| fc.to_s.underscore } ], allow_nil: false, message: "Select field type among these: #{ FieldSetting.get_field_classes.join(", ") }" }
68
74
  validates :field_group_id, presence: true
69
75
 
70
76
  # Slug
@@ -112,8 +118,9 @@ module Binda
112
118
  # Get field setting id from slug, without multiple calls to database
113
119
  # (the query runs once and caches the result, then any further call uses the cached result)
114
120
  @@field_settings_array = self.pluck(:slug, :id) if @@field_settings_array.nil?
115
- id = @@field_settings_array.select{ |fs| fs[0] == field_slug }[0][1]
116
- raise ArgumentError, "There isn't any field setting with the current slug.", caller if id.nil?
121
+ selected_field_setting = @@field_settings_array.select{ |fs| fs[0] == field_slug }[0]
122
+ raise ArgumentError, "There isn't any field setting with the current slug.", caller if selected_field_setting.nil?
123
+ id = selected_field_setting[1]
117
124
  return id
118
125
  end
119
126
 
@@ -134,5 +141,31 @@ module Binda
134
141
  self.allow_null = false if self.allow_null.nil?
135
142
  end
136
143
 
144
+ # Generates a default field instances for each existing component or board
145
+ # which is associated to that field setting. This avoid having issues
146
+ # with Binda::FieldSetting.get_id method which would throw an ambiguous error
147
+ # saying that there isn't any field setting associated when infact it's
148
+ # the actual field missing, not the field setting itself.
149
+ #
150
+ # A similar script runs after saving components and boards which makes sure
151
+ # a field instance is always present no matter if the component has been created
152
+ # before the field setting or the other way around.
153
+ def create_field_instances
154
+ structure = self.field_group.structure
155
+ field_class = self.field_type.pluralize
156
+ case
157
+ when structure.components.any?
158
+ structure.components.each do |component|
159
+ unless component.send(field_class).where(field_setting_id: self.id).any?
160
+ component.send(field_class).create!(field_setting_id: self.id)
161
+ end
162
+ end
163
+ when structure.board.present?
164
+ unless structure.board.send(field_class).where(field_setting_id: self.id).any?
165
+ structure.board.send(field_class).create!(field_setting_id: self.id)
166
+ end
167
+ end
168
+ end
169
+
137
170
  end
138
171
  end